• [Kotlin] 안드로이드스튜디오 RecyclerView 스크롤시 데이터가 섞이는 문제 해결방법

    2023. 3. 7.

    by. 하루플스토리

    반응형

    RecyclerView를 구현하고 데이터가 많아지면 스크롤 시 문제가 발생한다.

    이것에 대한 해결 방법이 구현 하는 당시 대부분의 블로그에는 이런 문제가 발생하는 것에 대해 이야기 하지 않는다.

    귀찮아서 설명하지 않는 것인지.. 아니면 아직 겪지 않아서인지 모르겠지만.. 애지간히 귀찮은 문제다.

     

    RecyclerView를 아래로 스크롤 하면 최상단에 있는 보이지 않게 된 시점의 뷰를 제일 아래로 끄집고 내려온다.

    기존 ListView의 성능을 개선하기 위해 이렇게 한 점은 좋은데 문제는 그 끄집고 온 뷰를 그대로 보여준다는 것이다.

     

    예를 들어 총 50개의 데이터가 있고 화면에는 5개의 데이터만 보이는 상황이다. 그럼 안드로이드는 뷰를 아마 5~6개를 재활용 해가면서 리스트를 구현할 것이다.

    여기서 나는 어떤 버튼을 클릭 시 리스트 전체를 우측으로 애니메이션 시켜 보겠다.

    빨간색 영역이 스마트폰에 실제로 보이는 영역이다.

     

    내가 원하는 결과는 위와 같을 것이다. 위 아래 뷰도 같이 애니메이션 되고 우측에 자리해야한다.

     

    하지만 놀랍게도 이딴식으로 처리한다.

    실제로 보이는 뷰 영역만 바뀌고 보이지 않는 뷰는 뷰의 변경이 적용되지 않게된다.

    결국 스크롤 하면 위, 아래 뷰들은 애니메이팅 되지 않은 채로 나타나게 된다.

     

    진짜 왜 이렇게 만들었는지 모르겠는데 검색해보니 나처럼 똑같이 생각하는 개발자가 많은 것 같았다.

    도통 이해가 되지 않는데 해결방법은 다행히 존재했다.

     

    해결방법

    1. NestedScrollView

    XML의 리사이클러뷰 주변에 NestedScrollView를 감싸게 되면 리스트 전체를 생성하게 된다. 예시로 든 50개라면 50개가 다 그려지게 된다. 하지만 리사이클러뷰를 사용하는 목적이 뷰를 재활용함으로써 성능 향상을 얻는 것인데 이러면 리스트뷰랑 다를게 없다. 만약 아래 방법으로 해결이 되지 않으면서 데이터의 갯수가 확실히 적은 경우라면 사용해도 되겠지만 애지간하면 쓰지 않는게 좋다.

     

    2. getItemViewType

    가장 간단한 방법으로는 getItemViewType을 오버라이드 해서 어댑터 클래스에 넣어주면 된다.

    override fun getItemViewType(position: Int): Int {
        return position
    }

    이러면 아이템의 제 위치를 리턴해주면서 형태를 유지시켜준다고 한다.

    하지만 이 방법으로 해결되지 않는 경우도 있는데 하필 나의 경우였다..

     

    3. onBindViewHolder

    onBindViewHolder는 새롭게 생성된 뷰가 있을 경우 호출되는 함수이다.

    즉, 내가 오른쪽으로 애니메이션을 했는지 안했는지 전역 변수를 만들고 해당 변수의 Boolean 값에 따라 뷰를 바로 처리하면 된다.

    when (isAnimating) {

       true -> 뷰를 오른쪽으로 그리기

       false -> 아무 행동 하지 않기

    }

    이렇게 하면 보이지 않는 뷰가 생성될 때 즉시 onBindViewHolder가 호출되면서 내가 원하는 대로 뷰가 그려질 것이다.

     

     

     


    뭐.. 여차저차 해결은 했지만 누가 지금 보이는 뷰만 컨트롤 하고 뒤죽박죽 뷰가 섞이길 원한다고 이렇게 만들었는지 모르겠지만 이런 문제는 RecyclerView 라이브러리 자체를 업데이트 해서 그냥 해결해주면 좋겠다. 그래야 개발자들 코드도 더 깔끔해질테니까..

    반응형

    댓글