본문 바로가기

안드로이드/팁

[Android] Recyclerview 클릭한 아이템 화면 중앙으로 이동

반응형

구현 기능 상세 내용

아래 사진처럼 탭에서 클릭된 아이템이 가려져 있을 경우  화면 중앙으로 이동

 

tabLayout은 탭으로써 기본 성질들을 갖고 있다보니 다양한 요구사항을 충족 시키기에 제약이 많다고 생각해 Recyclerview로 구현 했습니다.

 

(왼) 7번이 가려져 있는 상황에서 클릭 했을때, (우) 클릭후 7번 중앙 정렬

 

클릭한 탭을 화면 중앙으로 이동 시키기 위해 고려해야 하는 부분은 3가지 입니다. 

  • 디바이스 넓이 
  • 클릭한 탭의 넓이
  • 리싸이클러뷰에 적용한 패딩

그리고 스크롤시  layoutManager.scrollToPositionWithOffset(position, offset) 메소드가 사용 됩니다.

  • scrollToPositionWithOffset : 클릭한 포지션에서 offset 만큼 이동된 곳으로 scroll 
offset = (디바이스 넓이 / 2) - ((탭의 넓이 /2 ) + 리싸이클러뷰 패딩) 

 

 

현재 리스트에서 클릭한 리스트가 온전히 보이는지 체크 

layoutManager의 findLastCompletelyVisibleItemPosition, findFirstCompletelyVisibleItemPosition
두 메소드를 활용해 클릭한 아이템의 포지션이 저 위에 속하는지 체크합니다 .

  • findFirstCompletelyVisibleItemPosition : 온전히 다 보이는 첫번째 아이템의 포지션 
  • findLastCompletelyVisibleItemPosition : 온전히 다 보이는 마지막 아이템의 포지션 
패딩이 많이 들어간 경우 아이템이 온전히 보이는데도 원하는 값을 얻을수 없으니 주의해야 합니다.

 

 

현재 클릭한 탭의 넓이

각 탭의 담긴 넓이가 다를 경우엔 클릭한 탭의 넓이를 그때마다 가져와야 합니다.

가져오는 방법은 2가지입니다.

  • layoutManager.getChildAt(position)?.width 
  • recyclerview.findViewHolderForAdapterPosition(position).binding.root.width

첫번째

layoutManager.getChildAt(position) 활용시 주의해야할 사항이 있습니다.

기본적으로 리사이클러뷰는 뷰홀더를 재활용하기 때문에 메소드를 통해 가져오는 자식의 수는 현재 재활용중인 뷰홀더의 수만큼을 리턴합니다

= 전체 아이템이 20개이고 화면에 6개 정도 리스트가 보일 경우 getChildAt(10)을 할 경우 널일수 있음 

클릭한 시점에 제일 처음에 보이는 아이템을 0번째라고 계산하고 getChildAt에 사용될 position을 재가공 해야합니다.

 

두번째

var childViewHolder = binding.rvContent.findViewHolderForAdapterPosition(chipPosition)

val chipWidth = chilViewHolder.binding.root.width

 

 

마치며

이렇게 까지 구현해야 하나..? 라고 고민될 수 있습니다.

그럴땐 '유저에게 편리함을 가져다 주나?' 라고 생각 해보면 좋을 것 같습니다.

 

제가 작성한 코드로 유저들이 편리함을 느낀다면 그보다 뿌듯한 일은 없다고 생각합니다.

 

 

 

 

반응형