添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
酷酷的柑橘  ·  Android ...·  3 天前    · 
刚失恋的黄瓜  ·  android ...·  3 天前    · 
安静的手套  ·  RecyclerView.smoothScr ...·  3 天前    · 
很酷的莴苣  ·  RecyclerView之PagerSnap ...·  3 天前    · 
听话的硬盘  ·  Apache Tomcat 10 ...·  4 周前    · 
帅呆的西装  ·  Koa 框架 -- JavaScript ...·  4 月前    · 
微笑的手套  ·  5.0.0: ...·  5 月前    · 
细心的筷子  ·  Use the pgaudit ...·  9 月前    · 

Recyclerview는 많은 데이터를 제한된 영역 내에서 유연하게 스크롤 가능한 리스트로 표시해 주는 위젯입니다. Recyclerview는 뷰를 재활용하므로 앱 성능과 메모리 관리 측면에서도 매우 유용하며, 대규모 데이터를 효율적으로 쉽게 표시할 수 있습니다. 안드로이드 UI 툴킷의 중요한 구성 요소이며 많은 안드로이드 앱에서 널리 사용되고 있습니다.

Recyclerview를 사용할 때의 이점 중 하나는 커스텀이 매우 용이하다는 것입니다. 이 포스팅에서는 사용자의 특정 요구에 맞게 커스텀 하는 몇 가지 방법을 살펴보겠습니다.

Custom LayoutManager

Recyclerview를 커스텀 하는 한 가지 방법은 LayoutManager를 커스텀 하는 것입니다. LayoutManager는 아이템의 위치를 지정하고 측정하며 사용자에게 더 이상 표시되지 않는 항목을 재활용할 시기를 결정합니다.

다음은 Recycler View에서 중앙 item을 기준으로 확대/축소하는 CenterZoomLayoutManager 예시입니다.

  • LinearLayoutManager 를 상속하는 CenterZoomLayoutManager 클래스를 생성합니다.
  • generateDefaultLayoutParams() 에서 LayoutParams 개체를 생성합니다.
  • canScrollHorizontally() 을 true로 설정해 수평 스크롤을 지원합니다.
  • scrollHorizontallyBy() 에서 수평 스크롤에 대한 동작을 구현합니다.
  • 추가로 smoothScrollToPosition() 에서 스크롤 속도를 커스텀 합니다.
  • 마지막으로 Recyclerview에 setLayoutManager 로 적용합니다.
  • 이렇게 하면 중앙 item을 기준으로 확대/축소되는 효과가 Recyclerview에 적용됩니다.

    추가로 가운데 스냅 효과를 주기 위해 GravitySnapHelper 클래스를 생성해 Recyclerview에 적용합니다. GravitySnapHelper는 리스트가 스크롤 될 때 아이템을 화면 중앙으로 스냅 하는 효과를 주기 위한 클래스입니다.

    다음은 GravitySnapHelper 예시입니다.

    Gravity.CENTER 로 스크롤 효과 기준을 가운데로 설정하고, attachToRecyclerView 를 사용해 Recyclerview에 적용합니다.

    val snapHelper = GravitySnapHelper(Gravity.CENTER)
    snapHelper.setScrollMsPerInch(25f) //scroll speed
    snapHelper.attachToRecyclerView(recyclerView)

    Custom Adapter

    Adapter는 Recyclerview의 필수 항목으로 아이템 뷰를 생성하고 데이터를 바인딩 하는 역할을 합니다. Adpater를 커스텀 해 복잡한 레이아웃이 포함된 Recyclerview를 만들 수 있습니다.

    다음은 중첩 Recyclerview를 만들기 위한 Adapter 커스텀 예시입니다. 수직 Recyclerview 내부에 여러 뷰 타입의 수평 Recyclerview가 배치된 경우입니다.

    ParentAdapter와 ChildAdapter가 존재하며, ParentAdapter에서 데이터 뷰 타입에 따라 여러 개의 ViewHolder를 생성하고 바인드 합니다.

    getItemViewType 에서 데이터의 뷰 타입을 구분합니다.

    onCreateViewHolder 에서 뷰 타입에 따라 뷰 홀더를 생성합니다.

    onBindViewHolder 에서 뷰 타입에 따라 각 뷰 홀더에 바인드 합니다.

    ChildAdapter는 여러 개로 각각 사용해도 됩니다. 예제에서는 하나의 ChildAdapter를 이용했습니다. ChildAdapter item의 width와 layoutManager를 다르게 설정해 여러 레이아웃 타입을 만들었습니다.

    추가로 RecycledViewPool 을 이용해 스크롤 성능을 개선합니다.

    RecycledViewPool은 뷰 계층에서 일시적으로 제거된 뷰를 위한 저장소 풀입니다. 리스트의 각 항목에 대해 재사용할 수 있도록 하여 RecyclerView의 성능을 향상시키는 데 사용됩니다. 성능 향상을 위해 중첩된 Recyclerview에 하나의 RecycledViewPool을 공유합니다.

    또한 LinearLayoutManager에 initialPrefetchItemCount 로 중첩된 Recyclerview에서 미리 가져와야 하는 내부 항목 수를 설정합니다. 기본 값 2 대신 설정한 항목 수만큼 미리 바인딩 작업을 수행해 스크롤 될 때 버벅거림을 방지할 수 있습니다.

    (자세한 소스 코드를 보시려면 아래 링크를 클릭해 주세요.)

    ParentAdapter 예제 코드

    ChildAdapter 예제 코드

    Nested RecyclerView Scrolling

    중첩된 Recyclerview의 경우 스크롤이 잘되지 않는 경우가 발생할 수 있습니다. 부모 Recyclerview에서 스크롤 이벤트를 해결하는 동안 중첩된 다른 Recyclerview를 스크롤 하려고 하면 상호 간 터치 이벤트 간섭으로 인해 스크롤 동작이 잘 안 먹힐 수 있습니다. 이러한 경우 onInterceptTouchEvent 를 이용해 스크롤을 개선할 수 있습니다.

    onInterceptTouchEvent() 메서드는 ViewGroup 표면에서 터치 이벤트가 감지될 때마다 호출됩니다. true를 반환하면 MotionEvent가 가로채기 되며, 이는 하위 요소로 전달되지 않고 상위 요소의 onTouchEvent() 메서드에 전달됨을 의미합니다.

    MotionEvent.ACTION_DOWN : 손가락을 눌렸을 때

    MotionEvent.ACTION_MOVE : 손가락을 누르고 움직였을 때

    MotionEvent.ACTION_UP : 손가락 누른 것을 땠을 때

    아래 예시는 onInterceptTouchEvent를 커스텀 한 OrientationAware RecyclerView 입니다. 사용자가 손가락을 움직일 때 스크롤 방향이 Recyclerview 방향과 일치하면 터치 이벤트를 가로채고 그렇지 않으면 가로채지 않습니다.