[TIL] Recycler View in RecyclerView in Coodinator Layout

박봉팔·2024년 2월 15일
0

Coodinator Layout

프로젝트를 진행하다보면 상단에 원하는 내용을 넣고 스크롤시 해당 컨텐츠가 사라지면서 툴바나 탭메뉴들이 노출되게 하고 싶을경우 coodinatorLayout을 많이 사용하게 됐다.

하지만 점차 레이아웃의 깊이가 깊어지면서 여러가지 복합적인 문제가 발생하기 시작했다.


recyclerView in Coodinator

Scroll Behavior를 설정하기위해 Nested Scroll ViewRecycler ViewCoodinator Layout안에 선언한뒤 다시 그 안쪽에 컨텐츠를 출력해줄 recyclerView를 넣어줬다.

계속해서 테스트를 진행하던중 이상하게 해당 Fragment에서 유독 버벅거리는 현상이 심했다.

원인을 찾기위해 이것저것 테스트 하던 중 Layout Insfector를 확인해보니 Coodinator Layout안쪽에 선언해준 Scroll View내부에 있는 recycler View의 아이템들이 모두 생성되어 있었다.

Coodinator Layout이 자식 뷰간의 스크롤 behavior를 조정하기위해 Nested Scroll View를 최적화 하게되고 이 과정에서 recyclerView의 아이템이 전부 생성되었다.
(틀렸다면 댓글로 알려주시면 감사하겠씁니다.)


Change to recycler view

그래서 기존에 사용하던 Nested Scroll ViewRecycler View로 변경해준뒤 스크롤 방향이 같은 아이템의 경우 뷰타입을 따로 만들어 Recycler View에 직접 전달해 주도록 구현했다.

그리고 나머지 방향이 다른 Recycler ViewView Pager의 경우에도 뷰타입을 만들어 Recycler View내부에서 초기화 되도록 구현했다.


RecyclerView in RecyclerView

recyclerView내부에 또다른 recycler View를 구현하기위해 Sealed class로 각 요소들의 데이터 클래스를 만들어 줬다.

sealed class HomeItems {
    data class Header(
        var title: String
    ): HomeItems()

    data class CategoryVideo(
        var adapter: CategoryVideoAdapter
    ): HomeItems()

    data class CategoryChannel(
        var adapter: CategoryChannelAdapter
    ): HomeItems()

    data class RecommendVideo(
        var adapter: RecommendListAdapter
    ): HomeItems()
}

recycler view내부에서 recycler viewview pager를 초기화 하기위해 각각의 타입은 adapter를 전달받도록 구현했다.

헤더와 각각의 뷰들을 다르게 구현하기위해 부모 recycler view의 어댑터에는 다음과 같은 리스트를 전달했다.

    private var homeFragItems: MutableList<HomeItems> = mutableListOf(
        Header("카테고리명의 인기동영상"),
        CategoryVideo(CategoryVideoAdapter()),
        Header("카테고리명 연관 채널"),
        CategoryChannel(CategoryChannelAdapter()),
        Header("추천 동영상"),
        RecommendVideo(RecommendListAdapter())
    )

여기서 어떤방식으로 recycler View내부에 변경된 데이터를 submit해야할지 고민했었는데, 생각보다 간단한 방법으로 해결했다.

    private val categoryVideoAdapter by lazy { (homeFragItems[1] as CategoryVideo).adapter }
    private val categoryChannelAdapter by lazy { (homeFragItems[3] as CategoryChannel).adapter }
    private val recommendContentsAdapter by lazy { (homeFragItems[5] as RecommendVideo).adapter }

이와같이 부모 recycler view에 전달되는 리스트에 있는 원소들의 어댑터를 Fragment의 프로퍼티에 할당해 옵저빙된 데이터를 해당 어댑터로 submmiList하도록 구현했다.


오늘은 어땠나요?

밤샘 4일차...

어떻게 살아있는거지 지금?

profile
개발 첫걸음! 가보자구!

0개의 댓글