필자가 만들고 있는 앱의 목록 삭제 창의 페이지는 checkbox를 담고 있는 item의 리사이클러뷰로 이루어져 있다.
이 체크박스를 통해 data class의 check 값이 true 혹은 false가 되고 true가 된 data들을 대상으로 삭제 버튼 클릭시 삭제가 되는 방식이다.(여러 항목을 동시에 삭제할 수 있게 구현하기 위해 고안한 방식)
근데 문제가 생긴 것이 삭제 페이지 리사이클러뷰를 올렸다 내렸다 하면 체크하지도 않은 항목이 저절로 체크가 되는 문제가 발생한 것이었다.
여러차례 디버깅을 시도한 결과 리사이클러뷰 어댑터의 Holder 속 itemView들의 값 설정 함수안의 코드가 문제임을 알게되었다. (아래 코드블럭의 코드가 문제의 원인이었다.)
// editmode에서 memo의 check가 true면 itemView의 checkBox를 true인 상태로 내보냄(activity_main에서 선택한 뷰홀더를 체크박스 true인 상태로 보내기 위한 장치)
if (editmode == true && memo.check == true) {
itemView.checkBox.isChecked = true
}
리사이클러뷰는 화면에 보이는 뷰홀더의 개수 + 1개 만큼 준비를 하는데 스크롤을 내리면서 다른 위치의 itemView의 checkBox가 true가 되어 문제가 발생한 것 같다.
이를 해결하기위해 구조적으로 방식을 바꿔야 하나 고민도 했지만 다음과 같은 방법으로 문제를 해결했다.
// editmode에서 memo의 check가 true면 itemView의 checkBox를 true인 상태로 내보냄(activity_main에서 선택한 뷰홀더를 체크박스 true인 상태로 보내기 위한 장치)
if (editmode == true && memo.check == true) {
itemView.checkBox.isChecked = true
} else if (editmode == true && memo.check == false) { /*** 오류 해결 코드!! ***/ // 긴 목록에서 스크롤을 밑으로 내렸다 올렸다 하면 체크하지 않았던 항목이 체크가 되는 버그가 있었다.
itemView.checkBox.isChecked = false // 그것은 바로 위의 if문 코드 때문이었는데 이 else if문을 추가함으로써 문제가 해결되었다.
}
else if 문을 추가하여 memo.check의 값이 false라면 itemView의 checkBox도 false로 바꿔주는 방식이다.(memo는 필자가 사용한 data class의 이름이다. / editmode는 삭제모드시 어댑터가 다른 기능을 할 수 있도록 나누는 변수이다. editmode==true는 삭제모드임을 의미한다.)
굉장히 간단하지만 강력한 방법이었다.
하지만 처리 속도와 같은 효율성 부분에서는 부족한 부분이 있는 것 같다.
우선 이대로 사용하고 다른 방안이 생각난다면 수정하면 좋을것 같다.