Android RecyclerView의 Item 삭제 하는 방법(버그 회피)

2021. 12. 26. 23:05IT/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 값도 잘 나올 것으로 착각했다면 크나큰 오산이다.

 

나와 같은 삽질을 하지 않기를 바라며, 이 글을 남긴다.

반응형