Android

[Android/Kotlin] ViewPager 와 비슷한 RecyclerView 만들기

Question영 2022. 4. 4. 14:10
반응형

목적

RecyclerView 를 Scroll 이후 ViewPager 처럼 특정 페이지에 걸린것처럼 동작하게 하는 방법을 정리했습니다.

환경

  • Macbook
  • Android Studio

용어

  • RecyclerView
  • ViewPager2

구성

  • 코드 1. 현재 위치 계산 함수
  • 코드 2. 현재 위치에서 가변위치까지 에니메이션이 적용된 동작을 하게 하는 함수
fun getCurrentPosition(): Int {
    return LinearSnapHelper().findSnapView(layoutManager)?.run {
          layoutManager.getPosition(this)
    } ?: 0
}

fun moveToPosition(offset: Int) {
    val position = getCurrentPosition() + offset
    binding.rvContents.smoothScrollToPosition(position)
}

시나리오

  • RecyclerView 의 Scroll 진행
  • onScrollStateChanged 에서 이벤트를 감시 중 Scroll 완료시 임시 위치에서 멈추면 감지
  • 마지막 위치로 에니메이션 이동을 실행하여 자연스럽게 마지막 페이지의 정중앙으로 스크롤을 동작
val layoutManager = rvContents.layoutManager as LinearLayoutManager

rvContents.addOnScrollListener(object : RecyclerView.OnScrollListener() {
    override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
          super.onScrollStateChanged(recyclerView, newState)
          if (newState == RecyclerView.SCROLL_STATE_IDLE) {
            moveToPosition(0)
          }
    }

    override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
          super.onScrolled(recyclerView, dx, dy)
        // 선택시 정보 갱신
    }
})

고려사항

val snapHelper = LinearSnapHelper()
snapHelper.attachToRecyclerView(recyclerView)

LinearSnapHelperattachToRecyclerView 로 구현하는 방식도 있으나 횡 스크롤시 다소 시원스럽게 동작하지 않고 가속으로 스크롤하는 느낌을 살릴수가 없습니다.

약간 ViewPager 인데 하나씩 스크롤하는게 아닌 여러개 스크롤하다 멈추는 느낌이 좀 더 강하죠.

멈춤을 감지하여 자연스러운 위치배치시 해당 코드를 이용하는것도 생각해봤지만 리스너 등록 방식 같아 구현시 사용하지 않았습니다.

하지만 다른 느낌을 원한다면 해당 기능도 나쁘지 않습니다.

무엇보다 간단하니까요

마치며

마지막 선택된 정보는 선택시 정보 갱신 주석있는 부분에서 갱신이 가능합니다.

제 겪은 상황은 페이지의 양옆의 인덱스 정보를 노출하는 UI 를 표현시 해당 부분에 로직처리를 진행 했었고 관련 로직은 별도 기술하지 않았습니다.

참고

반응형