RecyclerView 삽질

Arakene·2024년 4월 27일

구조

RecyclerView

컨테이너

LayoutManager

measuring, positioning에 대한 역할을 함

Recycler

뷰 재사용을 담당하는 recyclerView의 핵심 클래스
Scrapped된 뷰와 recyclerPool을 가지고있음

  • Cache
    • 기본사이즈는 2
    • 캐시에 있는 viewHolder는 데이터 바인딩을 해제해거나 초기화하지 않음
  • RecycledViewPool
    • 기본사이즈는 5
    • 풀에 들어간 viewHolder는 바인딩 해제 및 초기화함 재바인딩 필요
  • 데드라인은 설정이 불가능한 것으로 보임
    이 두가지는 설정이 가능함

커스텀 시

  • generateDefaultLayoutParams()
    • 기본 레이아웃 파람 설정 (wrapContent, MatchParent)
  • onLayoutChildren(recycler: RecyclerView.Recycler?, state: RecyclerView.State?)
    • 실제 배치될 뷰를 그려줌
    • 여기서 뷰의 마진이나 스케일등을 지정한 후 addView를 통해 실제로 붙임

ItemAnimator

RecyclerView에 있는 고유 개념이 아니라 ViewGroup에 속한 속성
item이 add(), remove() 등 이벤트 발생 시 애니메이션 담당

LayoutAnimation

기본적으로 자식 뷰들이 모두 그려졌을 때, 1회 작동
scheduleLayoutAnimation()를 통해 재실행 가능

Adapter

많은 일을 하지만 주요작업은 ViewHolder를 생성함

cache에 데이터가 있는지 여부에 따라 생성 로직이 달라짐

ItemView 캐시에 있는 경우


1. LayoutManager가 recyclerView에게 position기반으로 뷰 요청
2. recyclerView가 Cache에 있는지 확인
3. 있으면 받은 데이터로 전달

ItemView 캐시에 없는 경우


1. 위 2번까지했는데 캐시에 뷰가 없으면 recyclerView가 adapter에게 viewType을 물어봄
2. recyclerView는 가져온 viewType으로 recyclerView Pool에게 viewHolder있는지 체크

ViewHolder 없는 경우


1. viewType에 대한 viewHolder가 없으면 recyclerView가 adapter에게 새 viewHolder 생성 요청, adapter는 생성한 viewHolder를 전달해줌

ViewHolder가 있는 경우


1. pool에 있는 viewHolder를 recyclerView에게 전달
2. recyclerView는 adapter에게 position, viewHolder을 넘겨 bind요청
3. adapter는 bind작업한 itemView를 전달, recyclerView는 전달받은 뷰를 layoutManager에게 전달

마지막 단계

layoutManager는 포지션으로 요청한 itemView를 배치하고 recyclerView에게 배치완료 사인을 보냄
recyclerView는 adapter에게 배치되었다고 전달

재활용

  1. LayoutManager가 화면에서 벗어난 itemView의 position을 계산해서 recyclerView에게 전달
  2. recyclerView는 itemView를 제거하고 adapter에게 알림
  3. recyclerView는 cache에게 제거되는 position의 itemView가 캐시에 남아있어도되는지 물어봄
    3-1. itemView이 생성된지 오래되었으면 cache -> pool에게 itemView 전달, pool은 adapter에게 메모리에서 제거하라고함
    3-2. 캐시에 저장해야한다면, cache에게 저장하라고 요청

재미있어보이는점?

  • ViewFlinger
  • GapWorker
profile
안녕하세요 삽질하는걸 좋아하는 4년차 안드로이드 개발자입니다.

0개의 댓글