(kotlin) recyclerview + databinding

박용석·2023년 8월 12일
1

RecyclerView란?

안드로이드 공식문서에는 대규모 데이터셋을 제한된 범위에 제공하기 위한 유연한 뷰라고 정의 한다.
이름이 리사이클러 뷰인 이유는 리스트 뷰와 다르게 매번 리스트 항복이 갱신될 때마다 기존에 사용했던 아이템 뷰를 재활용하기 때문이다.
많은 리스트 데이터들을 효율적으로 렌더링하기 위해 제공되는 뷰로, 기존에 쓰이던 리스트뷰 보다 성능과 유연성이 뛰어나 리스트뷰를 대체하고 있는 뷰 이다.

리사클러뷰와 데이터바인딩을 활용하여 MainActivity에 리스트를 뿌려주는 예제를 만들어 보자

먼저 데이터 바인딩을 사용하기 위해 Gradle Scripts > build.gradle(Module:app) 에서 아래의 코드를 추가하고 꼭 상단에 나오는 Sync now 를 눌러 적용을 시켜주자

build.gradle(Module: app)

    buildFeatures{
        dataBinding true
    }

MainActivity.kt

package com.example.recyclerview

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.recyclerview.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

    private  lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val itemList = mutableListOf<TodoItems>()
        for(i in 1..20){
            itemList.add(TodoItems("test $i"))
        }

        val adapter = TextAdapter(itemList)

        binding.rvTodo.layoutManager = LinearLayoutManager(this)
        binding.rvTodo.adapter = adapter

    }
}

뷰 바인딩을 초기화하고 뷰 바인딩을 사용하여 액티비티의 레이아웃을 설정한다.
TextAdapter 클래스를 인스턴스화하고 초기화된 itemList를 전달한다.
LinearLayoutManager의 현재 프래그먼트의 컨텍스트이며 LinearLayoutManager를 사용하여
RecyclerView의 아이템들을 수직으로 배치하도록 설정했다.
그리고 RecyclerView의 어댑터를 설정하고 adapter 변수에 저장된 ListItemAdapter 객체를 할당하여 RecyclerView에 목록 데이터를 표시해준다.

TodoItems.kt

package com.example.recyclerview

data class TodoItems(val text: String)

데이터 클래스로 mainactivity에서 itemList에 값을 추가할 때 사용

TextAdapter.kt

package com.example.recyclerview

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.recyclerview.databinding.RecyclerViewBinding

class TextAdapter(private val itemList: List<TodoItems>): RecyclerView.Adapter<TextAdapter.MyViewHolder>() {

    inner class MyViewHolder(private val binding: RecyclerViewBinding) : RecyclerView.ViewHolder(binding.root){
        fun bind(item: TodoItems){
            binding.item = item
            binding.executePendingBindings()
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val inflater = LayoutInflater.from(parent.context)
        val binding = RecyclerViewBinding.inflate(inflater, parent, false)
        return MyViewHolder(binding)
    }

    override fun getItemCount(): Int {
       return itemList.size
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        holder.bind(itemList[position])
    }
}

RecyclerView Adapter를 정의한다.
MyViewHolder class는 RecyclerView의 아이템 뷰를 위한 홀더 클래스로 뷰 바인딩을 통해 데이터를 아이템 뷰와 연결한다.
함수 onCreateViewHolder() 는 아이템 뷰 홀더를 생성하고 레이아웃 인플레이션을 수행한다.
함수 getItemCount() 는 아이템 목록의 크기를 반환한다.
함수 onBindViewHolder() 는 특정 위치의 데이터를 뷰 홀더에 바인딩해준다.
(alt + enter로 implement members를 클릭하여 함수들을 override 해주자)

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv_todo"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

recycler_view.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <variable
            name="item"
            type="com.example.recyclerview.TodoItems" />
    </data>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:text="@{item.text}"
        android:textSize="20dp" />
</layout>

data 태그를 추가하기 위해 코드부분 좌측 맨 위 ?xml 부분에 커서를 두고 alt+enter 또는 마우스 우클릭을 하여 show context action을 눌러서 convert to data binding layout 을 클릭해서 추가해 주자

variable 태그를 하나 추가하고 name을 입력한 다음 type은 data class로 선언했던 TodoItems.kt에 있는 패키지.클래스명을 입력해주면 된다. 그러면 레이아웃 내에서 변수로 사용이 가능해진다.

결과물

결과물을 보듯이 정말 간단할거라 생각했는데 막상 해보니 조금 복잡한 것 같다. 다음엔 좀 더 다양한 기능을 붙여서 진행을 해봐야겠다.

profile
슬기로운 개발 활동

1개의 댓글

comment-user-thumbnail
2023년 9월 1일

오 data binding 팁 감사합니다

답글 달기