[Android, Kotlin] Recycler View 안에 Recycler View 넣기, 중첩 RecyclerView
Android

[Android, Kotlin] Recycler View 안에 Recycler View 넣기, 중첩 RecyclerView

 

토이프로젝트로 영화 박스오피스 앱을 만들면서 꽤나 시간이 걸렸던 부분에 대해 기록한다.

 

 

 

본 영상처럼 Vertical Grid RecyclerView 안에 Horizon Linear RecyclerView를 넣도록 구현하고자 했다.

 

 

class HomeAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    private var data: List<HomeData> = emptyList()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): 
    RecyclerView.ViewHolder {
        return when (viewType) {
            TYPE_HEADER -> HeaderViewHolder(ItemHeaderBinding.inflate
                           (LayoutInflater.from(parent.context),parent,false))
            TYPE_LIKE -> LikeViewHolder(ItemRecyclerLikeBinding.inflate
                         (LayoutInflater.from(parent.context),parent,false))
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when {
            (holder is HeaderViewHolder && data[position].value is String) 
            -> holder.bind(data[position].value as String)
          
            (holder is LikeViewHolder) 
            -> holder.bind(data[position].values!!)
            else -> Unit
        }
    }

    override fun getItemCount(): Int = data.size

    override fun getItemViewType(position: Int): Int {
        return when (data[position].value) {
            is String -> TYPE_HEADER
            else -> TYPE_LIKE
        }
    }

    inner class HeaderViewHolder(private val binding: ItemHeaderBinding) :
        RecyclerView.ViewHolder(binding.root) {
        fun bind(header: String) {
            binding.title.text = header
        }
    }

    inner class FeaturedViewHolder(private val binding: ItemFeaturedBinding) :
        RecyclerView.ViewHolder(binding.root) {

        fun bind(featuredMovie: FeaturedMovie) {
            Glide.with(binding.root)
                .load(featuredMovie.posterUrl)
                .into(binding.featuredMovieImageView)
            binding.titleTextView.text = featuredMovie.title
            binding.detailTextView.text = 
            "${featuredMovie.country} ' ${featuredMovie.releaseYear}"
        }
    }

    inner class NormalViewHolder(private val binding: ItemMoviesBinding) :
        RecyclerView.ViewHolder(binding.root) {
        fun bind(movie: Movie) {
            binding.root.setOnClickListener {
                onClickMovie?.invoke(movie)
            }
            Glide.with(binding.root)
                .load(movie.posterUrl)
                .into(binding.posterImageView)

            binding.titleTextView.text = movie.title
            binding.detailTextView.text = "${movie.country} ' ${movie.releaseYear}"
        }
    }

    inner class LikeViewHolder(private val binding: ItemRecyclerLikeBinding) :
        RecyclerView.ViewHolder(binding.root) {

        init {
            binding.recyclerView.apply {
                adapter = LikeAdapter()
                layoutManager =
                    LinearLayoutManager
                    (binding.root.context, RecyclerView.HORIZONTAL, false)
            }
        }

        fun bind(likeMovies: List<LikeMovieEntity>) {
            binding.emptyLikeTextView.isGone = true
            binding.recyclerView.isVisible = true
            (binding.recyclerView.adapter as LikeAdapter).apply {
                addLikeMovie(likeMovies)
                notifyDataSetChanged()
                onClickLikeMovie = onClickLike
            }
        }
    }
    data class HomeData(val value: Any?, val values: List<LikeMovieEntity>?)

 

 

Main Adapter (바깥쪽 Vertical Grid RecyclerView Adapter) 에 대한 소스코드이다.

데이터를 새로운 HomeData라는 dataclass의 List 형태로 받아 이의 Type을 통해 view type을 설정한다.

찜 목록에 해당하는 데이터일 경우 view holder의 bind method에서 Like Adapter(안쪽 Horizon Linear Recyclerview Adapter)를 연결시켜주고, Like Adapter에 like movie entity list를 넘겨준다.

 

 

GitHub : https://github.com/HunSeongPark/box-office-MVVM

 

GitHub - HunSeongPark/box-office: Box Office app using MVVM Pattern.

Box Office app using MVVM Pattern. Contribute to HunSeongPark/box-office development by creating an account on GitHub.

github.com