[Android] RecyclerView의 ListAdapter에 대해 알아보자! .with 코틀린

MinGyun_06·2023년 4월 5일

android

목록 보기
5/7
post-thumbnail

📌시작에 앞서

이 글은 필자가 공부한 것을 정리하기 위해 작성한 글입니다. 글이 두서없을 수도 있으니 이 점 양해부탁드립니다.

RecyclerView란?

RecyclerView는 대량의 데이터들을 제한된 범위에 제공하기 위한 뷰로 기존에 사용하던 ListView보다 유연하다는 특징이 있습니다. 또 이름이 RecyclerView인 이유는 기존에 사용한 아이템 뷰를 재활용하기 때문입니다. 그리고 재활용을 위해 기본적으로 ViewHolder(뷰홀더) 패턴을 가지고 있습니다.

RecyclerView의 ListAdapter 란?

ListAdapter는 DiffUtil을 활용하여 item리스트를 업데이트 할 수 있는 기능을 추가한 Adapter라고 볼 수 있습니다.

  1. 아이템을 담을 레이아웃의 Data class를 준비합니다.
data class MyAdapter(
	val name: String,
    val age: Int
)
  1. DiffUtilCallBack 클래스 정의

DiffUtil을 사용하기 위해서 DiffUtil.Callback이라는 기능을 구현해야 합니다. 이때는 다음과 같은 함수를 구현하도록 요구합니다.

  • areItemsTheSame: 기존 어댑터와 새롭게 변경되는 어댑터 내용 안의 내용을 비교합니다. 리턴 타입은 boolean입니다.
  • areContentsTheSame: 기존 어댑터와 변경되는 어댑터 아이템 안의 내용을 비교합니다.

Callback 클래스를 object를 사용하여 구현해줍니다.

companion object{
	val diffUtil = object: DiffUtil.ItemCallback<MyAdapter>() {
    override fun areItemsTheSame(oldItem: DoodleImage, newItem: DoodleImage): Boolean {
        return oldItem.id == newItem.id
    }
    
    override fun areContentsTheSame(oldItem: DoodleImage, newItem: DoodleImage): Boolean {
        return oldItem == newItem
    }
}

위 코드에서 diffUtil이라는 변수에 Callback을 정의해 주었습니다.

이제 ListAdapter를 구현해주고 데이터 클래스와 뷰홀더를 붙여줍니다.

ListAdapter<MyAdapter, 리사이클러뷰.ViewHolder>(diffUtil)

ListAdapter에 아까 만든 데이터 클래스와 Callback을 정의해준 diffUtil을 붙여주었습니다.

ListApdater에서는 다음과 같은 주요 메서드를 사용할 수 있습니다.

  • getItem(position:Int) : protected 메서드이기 때문에 클래스 내부에서 구현할 때 사용합니다.
    어댑터 안의 List Indexing을 할 때 사용할 수 있습니다.
  • getCurrentList() : 어댑터가 가지고 있는 리스트를 가져올때 사용합니다.
  • submitList() : 어댑터에 새로운 데이터들을 갱신해줍니다.

그리고 ListAdapter에서는 다음 두개의 함수를 요구합니다.

  • onCreateViewHolder() : 미리 만들어진 뷰홀더가 없을 경우 새로 생성하는 함수(레이아웃 생성)
  • onBindViewHolder(): 뷰홀더가 뷰에 그려졌을 때 데이터를 바인드해주는 함수(뷰홀더가 재활용될때 실행)

이제 ListAdapter를 구현해주겠습니다.

class NewsAdapter: ListAdapter<MyAdapter, NewsAdapter.ViewHolder>(diffUtil){

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

        fun bind(item: NewsModel){
            binding.titleTextView.text = item.title

        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ViewHolder(
            ItemUserBinding.inflate(
                LayoutInflater.from(parent.context),
                parent,
                false
            )
        )
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.bind(currentList[position])
    }
    
    companion object {
        val diffUtil = object: DiffUtil.ItemCallback<NewsModel>() {
            override fun areItemsTheSame(oldItem: NewsModel, newItem: NewsModel): Boolean {
                return oldItem === newItem // === : hashcode(해시코드)까지 비교를 한다.
            }

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

🎈글을 마치며

이렇게 제가 공부한 것을 좀 정리하며 글로 적어보았습니다. 글을 좀 정신없이 쓴 감이 없지않아 있는데 코드가 좀 어지러워도 양해해주셨으면 좋겠습니다.😅 그럼 다음 글로 찾아뵙도록 하겠습니다. <(_ _)>

0개의 댓글