마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

ViewPager2로 무한 스크롤을 구현하는데 position이 이상하게 동작합니다

0 추천

안녕하세요, ViewPager2를 사용해서 커스텀 캘린더를 만들던 중 문제가 생겨서 여쭙고자 글 남겨봅니다.

 

제가 양옆으로 무한 스크롤을 구현하고 있는데요, 스크롤을 하면 FragmentStateAdapter가 새 프래그먼트를 생성할 때 원래의 position 값에서 +-1을 하지 않고 이상한 값을 넣는 것 같습니다. 로그를 찍어보니 +4를 하기도 하고도 하고, +1은 찍히지만 바로 넘어가서 position+2를 보여주기도 하는데, 왜 이러는 걸까요?

image

 

메인 액티비티에서 bottomNavigationView와 함께 3개의 프래그먼트를 호스팅하고 있고, 캘린더는 그 프래그먼트 중 하나에서 viewPager와 함께 호스팅하고 있어요. 그래서 그런걸까요?

처음 스크롤하면 항상 1월에서 다음 달이 log에는 찍히지만 건너뛰고 바로 3월을 보여주는데 이후부터는 그 방향대로 스크롤을 하면 잘 나옵니다. 그러다 반대편으로 스크롤하면 position이 사진의 아래 두 줄 처럼 나옵니다. 

 

아래 사진은 ViewPager 어댑터 코드입니다. 도와주시면 정말 감사하겠습니다ㅠㅠ

이륙사 (370 포인트) 님이 2022년 1월 30일 질문
이륙사님이 2022년 1월 30일 수정
로그에 찍힌 값이 포지션이 많나요? 숫자가 너무 커서 마치 뷰ID같은 것처럼 보이는데요.
그리고 getItemCount를 Int.MAX_VALUE를 주시면 모든 페이지를 이동할 때마다 새로운 프레그먼트가 생성이 되므로 재사용이 안되네요.

getItemId와 containsItem을 주석처리하시면 어떻게 되나요?
Int.MAX_VALUE를 전체 카운트로 설정하고, 초기 position을 Int.MAX_VALUE / 2로 설정해서 크게 나오는 것 같습니다. 엄청나게 많이 스크롤할 일은 없겠지만 어디까지 스크롤할지 몰라서 저렇게 크게 설정했는데, 좀 더 효율적인 방법이 있을까요?

그리고 위 문제는 createFragment()가 스크롤할 때마다 ui에서 보여주는 fragment를 생성하는 게 아니라서 생긴 문제였습니다. 그런줄 모르고 createFragment()가 실행될 때마다 onChangeMonth()로 textView를 변경했거든요..ㅎㅎ 미리 2~3개 생성해놓는 것 같더라구요.

registerOnPageChangeCallback를 등록해서 뷰모델에서 처리하는 방식으로 변경해서 해결했습니다!

그리고 말씀해주신 getItemId와 containsItem는 없어도 되는 부분이었습니다.
잘 됐네요. ViewPager2는 RecyclerView.Adapter를 기반으로 만들어졌기  때문에 동적으로  add, remove가 지원되는 걸로 압니다. RecyclerView.Adapter처럼, 외부에서 List<DateItem>를 넘겨주는 건 어떨까요.

답변 달기

· 글에 소스 코드 보기 좋게 넣는 법
· 질문에 대해 추가적인 질문이나 의견이 있으면 답변이 아니라 댓글로 달아주시기 바랍니다.
표시할 이름 (옵션):
개인정보: 당신의 이메일은 이 알림을 보내는데만 사용됩니다.
스팸 차단 검사:
스팸 검사를 다시 받지 않으려면 로그인하거나 혹은 가입 하세요.
...