
이 글은 필자가 공부한 것을 정리하기 위해 작성한 글입니다. 글이 두서없을 수도 있으니 이 점 양해부탁드립니다.
RecyclerView는 대량의 데이터들을 제한된 범위에 제공하기 위한 뷰로 기존에 사용하던 ListView보다 유연하다는 특징이 있습니다. 또 이름이 RecyclerView인 이유는 기존에 사용한 아이템 뷰를 재활용하기 때문입니다. 그리고 재활용을 위해 기본적으로 ViewHolder(뷰홀더) 패턴을 가지고 있습니다.
ListAdapter는 DiffUtil을 활용하여 item리스트를 업데이트 할 수 있는 기능을 추가한 Adapter라고 볼 수 있습니다.
data class MyAdapter(
val name: String,
val age: Int
)
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
}
}
}
}
이렇게 제가 공부한 것을 좀 정리하며 글로 적어보았습니다. 글을 좀 정신없이 쓴 감이 없지않아 있는데 코드가 좀 어지러워도 양해해주셨으면 좋겠습니다.😅 그럼 다음 글로 찾아뵙도록 하겠습니다. <(_ _)>