ListAdapter

BongKu·2023년 12월 27일
0

Android

목록 보기
26/30

ListAdapter

기존에 안드로이드 앱 개발을 하면서 RecyclerView의 Adapter를 만들 때 항상 RecyclerView Adapter를 사용했습니다.

하지만 아시다시피 RecyclerView Adapter는 데이터가 변경될 때마다 notifyDataSetChanged() 을 호출해서 변경되었다는 것을 알려주어야 했습니다.

이제껏 이런 방법만 있는 줄 알았는데, 안드로이드에 대해서 더 공부를 하다보니 ListAdapter라는 것이 있었습니다.

ListAdapter는 Jetpack 라이브러리 중 하나로 RecyclerView Adapter의 형태 중 하나로, 데이터가 변경될 때 효율적으로 화면을 갱신할 수 있습니다.

데이터 변경 시에만 필요한 항목을 업데이트할 수 있기 때문에 성능을 최적화할 수 있습니다.

ListAdapter<MyData, MyViewHolder>(MyDataDiffCallback())

DiffUtil.ItemCallback 을 구현해서 이전 데이터와 새로운 데이터의 차이를 계산합니다.

    override fun areItemsTheSame(oldItem: MyData, newItem: MyData): Boolean {
        return oldItem.id == newItem.id
    }

    override fun areContentsTheSame(oldItem: MyData, newItem: MyData): Boolean {
        return oldItem == newItem
    }

Adapter에서 submitList(val list: List<T>) 를 통해서 새로운 데이터를 업데이트하게 됩니다.

백문이 불여일견,,

간단한 예제 코드로 구현해 보았습니다.

acitivty_main.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=".MainActivity">

    <TextView
        android:id="@+id/main_text1"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:text="ListAdapter 예제"
        android:gravity="center"
        android:textSize="30dp"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/main_rv"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/main_text1"/>

</androidx.constraintlayout.widget.ConstraintLayout>

item_main.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=".MainActivity">

    <TextView
        android:id="@+id/main_text1"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:text="ListAdapter 예제"
        android:gravity="center"
        android:textSize="30dp"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/main_rv"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/main_text1"/>

</androidx.constraintlayout.widget.ConstraintLayout>

ExampleDiffUtilCallback

class ExamDiffUtilCallBack : DiffUtil.ItemCallback<String>() {
    override fun areItemsTheSame(oldItem: String, newItem: String): Boolean {
        return oldItem == newItem
    }

    override fun areContentsTheSame(oldItem: String, newItem: String): Boolean {
        return oldItem == newItem
    }
}

ExampleViewHolder

class ExamViewHolder(
    private val binding: ItemMainBinding
) : RecyclerView.ViewHolder(binding.root) {

    fun bind(str: String) {
        binding.itemText.text = str
    }

    companion object {
        fun valueOf(parent: ViewGroup): ExamViewHolder {
            val layoutInflater = LayoutInflater.from(parent.context)
            val binding = ItemMainBinding.inflate(
                layoutInflater,
                parent,
                false
            )
            return ExamViewHolder(binding)
        }
    }
}

ExampleAdapter

class ExamAdapter : ListAdapter<String, ExamViewHolder>(ExamDiffUtilCallBack()) {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ExamViewHolder {
        return ExamViewHolder.valueOf(parent)
    }

    override fun onBindViewHolder(holder: ExamViewHolder, position: Int) {
        holder.bind(getItem(position))
    }

    override fun submitList(list: MutableList<String>?) {
        super.submitList(list)
    }
}

MainActivity

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

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

        setContentView(binding.root)

        val fakeDataList = mutableListOf<String>()
        fakeDataList.add("Item 1")
        fakeDataList.add("Item 2")
        fakeDataList.add("Item 3")
        fakeDataList.add("Item 4")
        fakeDataList.add("Item 5")
        val adapter = ExamAdapter()
        adapter.submitList(fakeDataList)

        with(binding){
            mainRv.adapter = adapter
            mainRv.layoutManager = LinearLayoutManager(this@MainActivity)
        }
    }
}
  • LayoutManager의 경우 굳이 Activity에서 지정해주지 않아도 됩니다.
    xml파일에서 속성으로 지정해 주어도 됩니다 !
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/main_rv"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/main_text1"/>
profile
화이팅

0개의 댓글