boostcampwm-2022 / android06-mogle

🔮 모글(mogle) - 지도에 쓰는 다이어리, 기록, 일기
32 stars 4 forks source link

모먼트 리스트 정렬 시 스크롤 맨 위로 안올라가는 문제 #47

Closed jaemin-Yoo closed 1 year ago

jaemin-Yoo commented 1 year ago

❌ 버그 설명

모먼트 리스트 정렬 시 스크롤 맨 위로 안올라가는 문제

🚶‍♂️ 접근 방법

접근하기 위한 단계를 작성해 주세요. 1, 바텀 시트에서 정렬 카테고리 선택

  1. 정렬 시 리스트가 업데이트 됨
  2. 그러나 리스트의 최상단을 보여주지 않음(스크롤을 위로 더 올릴 수 있음)

🧐 예상 행동

버그가 발생하지 않고 기존에 예상했던 행동을 작성해 주세요.

📷 Screenshots

버그를 설명하는 데 도움이 되는 스크린샷을 추가해 주세요. Animation

📱 Smartphone

버그가 발생한 기기 정보를 입력해 주세요.

  • Device: [e.g. Samsung Galaxy S21]
  • Version : [e.g. 31]

📢 추가 사항

해당 버그에 관한 추가 및 특이 사항을 작성해 주세요.

jaemin-Yoo commented 1 year ago

문제 발생

모먼트 리스트 구현 다했는데 정렬 할 때 스크롤이 맨 위로 안올라간다.

그럴 수 있다. 리스트 위치들이 바뀌면서 내가 보고 있는 스크롤은 고정되어있기 때문에 이런 문제가 발생했다고 생각했다.

심지어 다른 예제에서 페이징 라이브러리를 사용하면서 동일한 문제들이 다 있었다.

그래서 당연히 Paging3 라이브러리의 문제라고 생각했다. (처음에는 그랬음)

접근

처음에는 다른 예제들은 이런 문제가 없다고 생각해서 다른 점을 찾아보다가 PagingSource 부분에서 다른 점이 있다는 것을 확인했다. Room에서 PagingSource를 반환하도록 구현이 되어있어서 그런가? 하는 의문이 들었다. PagingSource를 반환하기 때문에 어떤 값을 정의하고 getRefreshKey 도 어떤식으로 정의되어있는지 모른다. 그래서 다시 직접 구현하는 것으로 바꿔보았다.

그러나 문제는 여전히 발생했다. 그러면 뭐가 문제일까… paging scroll 관련해서 검색해봐도 내가 원하는 답을 찾을 수 없었다. 이상했다. 왜 자료가 없을까. 문제를 찾기 전에 여러 해결책들을 시도해보았다. 정렬할 때 스크롤을 최상단으로 올리는 방법. 현재 스크롤이 어느정도 위치에 있는지 계속 확인도 해보았다. 그러던 중 페이징이랑은 관련없다는 것을 알았다.

해결

DiffUtil의 콜백 반환값들을 false 로 주어 전부 업데이트 되도록 해봤다. 그러니 내가 원하던 최상단으로 스크롤이 위치하는 것이었다. 그래서 DiffUtil쪽에 문제가 있다는 것을 알아냈고 기존에 있는 아이템들의 순서가 바뀌다보니까 이와 같은 현상이 나타나는 것이었다. 만약 새로 불러와야하는 아이템들이라면 정상작동 했을 것이다. 그래서 아이템이 이동하는 시점을 알아내 스크롤을 맨 위로 올려주었다.

private val adapterDataObserver = object : RecyclerView.AdapterDataObserver() {
    override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {
        super.onItemRangeMoved(fromPosition, toPosition, itemCount)
        binding.bottomSheet.rvMoments.scrollToPosition(0)
    }
}
// observer 등록 (onViewCreated)
momentAdapter.registerAdapterDataObserver(adapterDataObserver)

// observer 해제 (onDestroyView)
momentAdapter.unregisterAdapterDataObserver(adapterDataObserver)