리스트뷰의 각 아이템에 체크박스를 추가하였습니다.
사용자가 체크를 하면 getview에서 체크된 view의 배경을 다른 색으로 주어 체크 표시가 가능하도록 했구요.
그런데 문제는 체크 후 위아래로 스크롤을 하면 만약 두개를 체크했다면
약 한페이지 정도를 아래로 스크롤하면 두개의 아이템이 체크되어 있는 현상이 발생하네요.
스크롤을 계속 내려면 역시 두개씩 체크가 되어 있습니다.
다시 스크롤을 위로 올리면 지금까지 체크된 모든 아이템이 다 표시되구요.
이 상태에서 아무 아이템이나 체크를 풀고 스크롤 하면 체크 표시된 모든 아이템이 체크가 풀리네요..
이게 무슨 문제인지 아시는 분 계신가요?
안드로이드의 AdapterView 들은 화면크기에 맞는 자식뷰를 생산하고 그것들을 재활용합니다.
예를 들자면 7개의 아이템이 리스트뷰에 있고 스크롤을 했을때 1번 아이템이 7번 밑으로 와서 붙는겁니다.
그러니까 1번에 체크를 해놨다가 스크롤을 내리면 8번 아이템이 내가 체크하지도 않았는데도 튀어나오게 되는거죠
이런 원리로 인해 체크박스를 이용하는 방법은
첫번째. Checkable 을 implements 한 레이아웃을 ListView의 아이템으로 사용하여 ListView의 멀티초이스
모드를 이용하는 방법이 있습니다. 하지만 해당방법은 리스트뷰 아이템 클릭 영역을 모두 활용하기 때문에 제약이 있습니다.
두번째. Adapter를 extends 하시고 멤버에 Map<Integer, Boolean> 을 포함하여 key를 position 체크여부를 boolean
값으로 관리하면서 getView에서 셋팅해주면 되겠습니다. 물론 어댑터에서 체크한 목록 받아오는 메서드등도 작성해야 액티비티등에서
이용하실 수 있겠죠
아 네.. 제가 이전 소스에선 android.R.layout.simple_list_item_multiple_choice 을 사용했더라구요 ㅡㅡ;
그래서 이번엔 Checkable을 implements 하는 클래스를 만들어 테스트를 해보니 이번에도 체크후 스크롤 하면 체크표시가 사라지네요.
이상해서 ListActivity의 onListItemClick() 함수를 막고 리스트를 터치하니 체크가 정상적으로 동작을 합니다.
또 테스트 해본게 CheckBox의 속성 android:clickable="ture" 설정 한 후 체크박스를 터치하여 체크표시를 하면 스크롤 했을 때 체크가 사라지고 같은 설정에서 체크박스 부분이 아닌 다른 부분을 터치하면 체크가 정상동작 하네요. ㅡㅡ;;
이런 현상은 왜 그런지 혹시 아시나요?
멀티초이스 모드 사용시는 체크와 리스트아이템 클릭에 대한 이벤트를 같이 사용 할 수 없는 건가요?
우선 구현하실때 커스텀 레이아웃 안의 CheckBox의 focusable을 false로 두셔야 합니다.
멀티 초이스모드를 사용한다는것은 개별 체크박스를 클릭하는게 아니고 리스트 아이템 전체를 클릭하는게 선택모드로 동작한다는 의미이기 때문에 CheckBox가 포커스를 가져가면 안됩니다. 멀티초이스 모드 사용시 체크와 리스트 아이템 클릭을 구분하시고 싶으시다면 아까 제가 답변적어준대로 Map이나 List등으로 각 position에 대한 체크값을 관리하셔서 사용하시면 되겠습니다.
그리고 Checkable을 implements 하실때 isChecked(), setChecked(boolean checked), toggle() 이렇게 모두 구현을 해주셔야 합니다.
Checkable을 구현하는 커스텀 레이아웃을 만드실때 멤버로 CheckBox를 선언해두고 생성자에서 findViewById()로 인스턴스를 얻어두신뒤에 isChecked()메서드에는 해당 인스턴스.isChecked()해서 리턴해주시고 setChecked()에서는 파라미터로 넘어오는 값을 체크박스 인스턴스.setChecked()에 넣어주시고 toggle()은 지금 있는거 반대로 해주시면 되니까 isChecked()로 체크여부 받아오신뒤에 다시 setChecked에 반대값 넣어주시면 되겠습니다.
간단한 방법으로.. 선택된 아이템에 대해서는 check 표시를 하고 아닌 항목에 대해서는 check를 풀도록 바꿔보세요
if (selected) {
view.check();
} else {
view.uncheck();
}
뭐 이런식으로...
하지만 그 방법보다는 아래 사이트의 listview.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); 방식이 좋아 보입니다.
http://www.androidpeople.com/android-listview-multiple-choice-example