본문 바로가기
개발 공부/안드로이드 스튜디오(코틀린)

안드로이드스튜디오(notifyDataSetChanged)

by momo'sdad 2023. 10. 18.

리스트를 업데이트하는 5가지 방법

3-1. 전체 업데이트

3-1-1. notifyDataSetChanged

 

사용하기 편해서 나 같은 초보자들이 가장 많이 사용하는 메서드이다.

많은 인터넷 글에서 "recyclerView의 리스트를 업데이트할 때 사용하는 메서드" 정도로 소개하고 있다.

하지만 좀 더 자세히 알고 상황에 맞게 사용해야 하지 않을까 싶다. (이 글을 작성하는 이유이기도 하다)

 

notifyDataSetChanged는 리스트의 크기와 아이템이 둘 다 변경되는 경우에 사용하면 된다.

어댑터에게 "야! 이제 리스트 크기도 변할 거고, 아이템도 새로운 게 들어올 거야. 다시 새로 그려!"라고 알려주는 것이다.

하지만 리스트의 크기는 동일한데 아이템만 바뀌는 경우라든지

아이템의 순서만 살짝 바뀌는 경우 등등에는 굳이 새로 그릴 필요가 없다.

마치 빙고 게임을 할 때 매 판마다 빙고판을 다시 만들 필요가 없는 것처럼 말이다.

 

notifyDataSetChanged는 어느 상황에서나 사용 가능하다는 장점이 있으나

퍼포먼스적인 측면에서 생각했을 때 앞으로 설명할 4가지 상황에 맞게 메서드를 사용해주는 것이 좋다.

 

3-2. 변경

3-2-1. notifyItemChanged

  • notifyItemChanged(position: Int)
  • notifyItemChanged(position: Int, payload: Any?)
  • position: 변경된 아이템의 위치
  • payload: 여기를 참고

 

과일을 주제로 빙고판을 채우고 있는데 실수로 채소를 1개 적었다고 치자.

굳이 빙고판을 다시 처음부터 그리고 단어를 채울 필요는 없을 것이다.

그냥 그 단어만 지우고 다시 적으면 되니까.

 

recyclerView도 마찬가지다.

어느 특정 위치의 아이템만 변경해야 한다면 notifyItemChanged를 사용하면 된다.

payload는 잘 설명되어 있는 블로그가 있어서 걸어둔 링크를 확인하면 될 것 같다.

 public final void notifyItemChanged(int position) {
            mObservable.notifyItemRangeChanged(position, 1);
        }

참고로 notifyItemChanged는 notifyItemRangeChanged를 호출하는 메서드이다.

이때 아이템의 크기를 1로 설정하여 호출한다.

 

3-2-2. notifyItemRangeChanged

  • notifyItemRangeChanged(positionStart: Int, itemCount: Int)
  • notifyItemRangeChanged(positionStart: Int, itemCount: Int, payload: Any?)
  • positionStart: 변경된 첫 번째 아이템의 위치
  • itemCount: 변경된 아이템의 개수
  • payload: [목차 3-2] 참고

 

변경된 아이템이 1개가 아니라 연속된 여러 개의 아이템이라면 이 메서드를 사용하면 된다.

0번 포지션 ~ 10번 포지션 이런 식으로 말이다.

변수는 첫번째 아이템의 위치와 변경된 아이템의 개수를 넘겨주면 된다.

  public void notifyItemRangeChanged(int positionStart, int itemCount) {
            notifyItemRangeChanged(positionStart, itemCount, null);
        }

참고로 payload 값 안 넘겨주면 알아서 null을 넣어 호출한다.

 

3-3. 추가

3-3-1. notifyItemInserted

  • notifyItemInserted(position: Int)
  • position: 새로 삽입된 아이템의 위치

 

특정 위치에 아이템이 새로 삽입되었다면 이 메서드를 사용하면 된다.

주의할 점은 position은 0부터 시작한다는 것이다.

우리가 볼 때 리스트의 10번째 아이템은 position 값이 9라는 것이다.

 

3-3-2. notifyItemRangeInserted

  • notifyItemRangeChanged(positionStart: Int, itemCount: Int)
  • positionStart: 삽입된 첫 번째 아이템의 위치
  • itemCount: 삽입된 아이템의 개수

 

연속된 여러 개의 아이템이 삽입될 때는 이 메서드를 사용하면 된다.

 

3-4. 삭제

3-4-1. notifyItemRemoved

  • notifyItemRemoved(position: Int)
  • position: 삭제된 아이템의 위치

 

추가와 메커니즘이 같아서 설명 생략.

특정한 아이템 1개를 삭제할 때 사용한다.

 

3-4-2. notifyItemRangeRemoved

  • notifyItemRangeRemoved(positionStart: Int, itemCount: Int)
  • positionStart: 삭제된 첫 번째 아이템의 위치
  • itemCount: 삭제된 아이템의 개수

 

마찬가지이다. 연속된 여러 개의 아이템이 삭제될 때 사용.

 

3-5. 이동

3-5-1. notifyItemMoved

  • notifyItemMoved(fromPosition: Int, toPosition: Int)
  • fromPosition: 아이템의 이전 위치
  • toPosition: 아이템의 새로운 위치

 

아이템이 이동했을 때 사용하는 메서드이다.

순위를 나타내는 리스트에서 특정 인물이 등수가 올랐다거나

메모를 꾹 눌러 순서를 변경한다거나 등의 상황에서 사용한다.

notifyItemRangeChanged 메서드를 사용하니 움짤처럼 fade 효과가 들어감.

recyclerView.itemAnimator = null

recyclerView의 itemAnimator 속성에 null 값을 주면 된다.

레이아웃에서 설정하고 싶었는데 안 되는 듯하다.

클래스 파일에서 설정해주면 된다.

반응형