문제점
리사이클러 뷰의 데이터가 변경됐을 때 notifyDataSetChanged()로 UI를 갱신할 경우 발생한다.
해결법
notifyDataSetChanged()를 사용하기 보단 각 상황에 맞는 함수를 사용한다.
notifyItemChanged(int)
notifyItemInserted(int)
notifyItemRemoved(int)
notifyItemRangeChanged(int, int)
notifyItemRangeInserted(int, int)
notifyItemRangeRemoved(int, int)
notifyDataSetChanged는 최후의 수단으로 사용할 것을 권한다.
해결법을 보고 든 개인적인 생각으론 notifyDataSetChanged는 리사이클러 뷰에 자식으로 들어갈 전체 데이터가 변하는 상황에 맞게 리사이클러 뷰의 어댑터가 뷰홀더 전체를 지웠다가 다시 렌더링하기 위한 것이란 생각이 든다.
notifyDataSetChanged가 비효율적인 상황이라고 생각되는 것과 그에 대한 해결책?에 대해 2개만 이야기하자면 아래와 같다.
- 맨 아래에 아이템을 하나씩만 추가
- notifyItemInserted로 하나씩 추가된다는 것만 알리면 된다.
- 중간의 아이템을 삭제
- notifyItemRemoved로 중간 아이템을 삭제했단 것을 알리고 notifyItemRangeChanged로 지워진 부분부터만 데이터들이 각 뷰홀더에 맞게 변해야 한단 것을 알리면 된다.
특정할 수 있는 아이템에 대해서 처리를 할 땐 전체를 지우고 다시 그릴 필요 없이 해당 아이템들만 변경하면 되는 것이므로 notifyDataSetChanged를 사용하는 것은 지양해야겠다고 생각되었다.
위 내용 외에도 notifyDataSetChanged를 사용하면 삭제 또는 추가에 대한 애니메이션이 보이지 않아 바뀐지 잘 모를 수 있는 상황이 발생할 것으로 보인다.
참고