2021. 12. 26. 23:05ㆍIT/Android
각종 Android RecyclerView를 찾아보면 아주 간단하게 item을 삭제하는 방법이 소개되어 있다.
binding.recyclerView.adapter!!.notifyItemRemoved(position)
하지만, 실제로 잘 동작하는지는 직접 코드를 입력해서 테스트 해봐야 알 수 있다.
나의 경우, 분명 item을 List에서 삭제하고, 위 함수를 호출했지만, RecyclerView의 아답터에 있는 아이템 리스트의 사이즈는 갱신되지 않았다.
즉, 데이터 사이즈는 분명 삭제해서 (-1) 되었지만, 뷰에서 받아오는 position값은 삭제되지 않은 position값을 뷰가 알려준다.
이 버그는 보통 리스트에 아이템이 3개 있다고 가정하면,
시나리오1) 두번째 아이템 삭제 -> 리스트 사이즈 2, 뷰 포지션은 0-1(인덱스 개념)을 가져야 한다.
시나리오2) 이제 2개 중 마지막 아이템(포지션 값 1)을 삭제하려고 하면, 에러가 발생한다. 이때의 에러는 데이터 리스트에는 2개의 아이템 밖에 없는데, 뷰 포지션 값이 1(size() -1 값)이 아닌, 2를 리턴한다.
여기서 디버그 해보면, 리스트의 size() 값은 문제 없이 갱신되어 찍힌다. 하지만 뷰 포지션 값은 notifyItemRemoved() 함수를 호출했음에도 불구하고 엉뚱한 position 값을 리턴해서 IndexOutofRangeException을 발생 시킨다.
즉, 리사이클뷰에서 item을 삭제하기 위해서는 또다른 꼼수가 필요하다. 바로 notifyItemRangeRemoved() 를 뒤에 바로 같이 호출해주면 된다는 것.
binding.recyclerView.adapter!!.notifyItemRemoved(position)
binding.recyclerView.adapter!!.notifyItemRangeRemoved(position, list.size() - position)
구글링에서 나오는 간단한 레퍼런스와 예제들에서는 이야기 해주지 않는 내용이다. notifyItemRemoved()로 아이템이 눈에서 사라지는 것을 확인했으니, 당연히 position 값도 잘 나올 것으로 착각했다면 크나큰 오산이다.
나와 같은 삽질을 하지 않기를 바라며, 이 글을 남긴다.
'IT > Android' 카테고리의 다른 글
프리다(Frida)를 이용한 안드로이드 루팅 감지 우회 (5) | 2022.10.03 |
---|---|
안드로이드 12, java.lang.IllegalArgumentException 오류 수정 방법 (0) | 2022.02.06 |
안드로이드 TabLayout 탭의 아이콘 색상 자동으로 변경 (0) | 2022.01.08 |