본문 바로가기
안드로이드 코틀린

[Kotlin][Android] 간단한 중첩 리사이클러뷰 만들기

by teamnova 2022. 2. 27.

세로로 스크롤되는 리사이클러뷰A 안에 가로로 스크롤되는 리사이클러뷰B가 있는 뷰를 만들어보겠습니다.

코드는 sdk 28인 상태에서 테스트되고 뷰바인딩이 사용됩니다.

 

만들 것은 다음과 같습니다.

  • 리사이클러뷰로 보여줄 아이템 클래스
  • 리사이클러뷰A 아이템 레이아웃
  • 리사이클러뷰A 어댑터
  • 리사이클러뷰B 아이템 레이아웃
  • 리사이클러뷰B 어댑터
  • 액티비티 레이아웃
  • 액티비티 클래스

Palette.kt

data class Palette(
    val name: String,
    val colors: ArrayList<String>
)

item_palette.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:layout_margin="10dp"
    android:background="@color/teal_700"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_palette"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginVertical="10dp"
        android:gravity="center_horizontal"
        android:textColor="@color/black"
        android:textSize="20sp" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_color"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />
</LinearLayout>

PaletteAdapter.kt

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

    lateinit var items: ArrayList<Palette>

    fun build(i: ArrayList<Palette>): PaletteAdapter {
        items = i
        return this
    }

    class ViewHolder(val binding: ItemPaletteBinding, val context: Context) :
        RecyclerView.ViewHolder(binding.root) {
        fun bind(item: Palette) {
            with(binding)
            {
                tvPalette.text = item.name
                rvColor.apply {
                    adapter = ColorAdapter().build(item.colors)
                    layoutManager =
                        LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
                }
            }
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PaletteAdapter.ViewHolder =
        ViewHolder(
            ItemPaletteBinding.inflate(LayoutInflater.from(parent.context), parent, false),
            parent.context
        )

    override fun onBindViewHolder(holder: PaletteAdapter.ViewHolder, position: Int) {
        holder.bind(items[position])
    }

    override fun getItemCount(): Int = items.size
}

 

item_color.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/tv_color"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="10dp"
    android:background="@color/black"
    android:gravity="center"
    android:textColor="@color/purple_500"
    android:textSize="50sp" />

ColorAdapter.kt

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

    lateinit var items: ArrayList<String>

    fun build(i: ArrayList<String>): ColorAdapter {
        items = i
        return this
    }

    class ViewHolder(val binding: ItemColorBinding) : RecyclerView.ViewHolder(binding.root) {
        fun bind(item: String) {
            binding.tvColor.text = item
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ColorAdapter.ViewHolder =
        ViewHolder(ItemColorBinding.inflate(LayoutInflater.from(parent.context), parent, false))

    override fun onBindViewHolder(holder: ColorAdapter.ViewHolder, position: Int) {
        holder.bind(items[position])
    }

    override fun getItemCount(): Int = items.size
}

activity_palette.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".PaletteActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_palette"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

PaletteActivity.kt

class PaletteActivity : AppCompatActivity() {

    lateinit var binding: ActivityPaletteBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityPaletteBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.rvPalette.apply {
            adapter = PaletteAdapter().build(palettes)
            layoutManager =
                LinearLayoutManager(this@PaletteActivity, LinearLayoutManager.VERTICAL, false)
        }
    }

    val palettes = arrayListOf<Palette>(
        Palette("cozy", arrayListOf("pink", "purple", "sky blue", "white")),
        Palette(
            "rainbow",
            arrayListOf("red", "orange", "yellow", "green", "blue", "indigo", "purple")
        ),
        Palette(
            "Healthy Leaves",
            arrayListOf("Olive Green", "Lime Green", "Yellow Green", "Green")
        ),
        Palette("korea", arrayListOf("white", "black", "blue", "red")),
        Palette("usa", arrayListOf("blue", "red", "white")),
        Palette("italy", arrayListOf("green", "white", "red")),
        Palette("china", arrayListOf("red", "yellow")),
        Palette("google", arrayListOf("red", "yellow", "green", "blue")),
    )
}