아이템을 실제로 보여주는 화면인 rcv_list_item.xml을 만들어준다. user라는 이름의 변수로 <data> 태그 안에 만들어 주고, 값들이 들어갈 텍스트뷰에 맞춰 ProfileData에 존재하는 변수를 넣어준다.
이제 뷰 홀더를 만들어주는데, 기존 뷰 홀더와 어떠한 차이가 있는지 확인해보자.
기존 ViewHolder
class BaseVH(view : View) : RecyclerView.ViewHolder(view){
val name : TextView = view.findViewById(R.id.item_name)
val age : TextView = view.findViewById(R.id.item_age)
fun onbind(data : ProfileData){
name.text = data.name
age.text = data.age.toString()
}
}
기존의 작성하던 뷰 홀더였다면 이런 식으로 코드를 작성해서 뷰에 값들을 넣어주었을 것이다.
그러나 데이터 바인딩을 사용하게 되면 다음과 같이 바뀐다.
데이터 바인딩을 사용한 ViewHolder
class ProfileVH(val binding : RcvListItemBinding) : RecyclerView.ViewHolder(binding.root){
fun onBind(data : ProfileData){
binding.user = data
}
}
굉장히 코드가 짧아진다. RcvListItemBinding은 파스칼 표기법으로 바뀐 rcv_list_item.xml의 클래스다.
user라는 변수에 어댑터를 통해 전달돼 온 ProfileData를 넣어준다. 그리고 View타입을 받는 것이 아니라
바인딩된 클래스를 받는 것도 하나의 차이점이다.
다음은 어댑터를 만들어 줄 차례이다. 어댑터에서는 onCreatViewHolder에서 차이점이 생긴다.
기본 Adapter
class BaseAdapter (val context : Context) : RecyclerView.Adapter<BaseAdapter.BaseVH>(){
var data = listOf<ProfileData>()
...
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseAdapter.BaseVH {
val view = LayoutInflater.from(context)
.inflate(R.layout.rcv_list_item, parent, false)
return BaseVH(view)
}
...
}
기존과 같이 어댑터를 작성했다면 onCreateViewHolder는 다음과 같았을 것이다.
ProfileAdapter.kt
class ProfileAdapter (private val context : Context) : RecyclerView.Adapter<ProfileAdapter.ProfileVH>(){
var data = listOf<ProfileData>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProfileVH {
val binding = RcvListItemBinding.inflate(
LayoutInflater.from(context), parent, false)
return ProfileVH(binding)
}
...
}
데이터 바인딩을 사용하면 뷰 홀더에 View를 보내주는 것이 아닌 바인딩 클래스를 보내줘야 하므로 코드도 그에 맞춰 바뀌게 된다.
데이터 바인딩을 사용한 어댑터의 코드 전문을 보면서 천천히 살펴보자.
package org.techtown.databinding
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import org.techtown.databinding.databinding.RcvListItemBinding
class ProfileAdapter (private val context : Context) : RecyclerView.Adapter<ProfileAdapter.ProfileVH>()
{
var data = listOf<ProfileData>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProfileVH {
val binding = RcvListItemBinding.inflate(
LayoutInflater.from(context), parent, false)
return ProfileVH(binding)
}
override fun getItemCount(): Int = data.size
override fun onBindViewHolder(holder: ProfileVH, position: Int) {
holder.onBind(data[position])
}
class ProfileVH(val binding : RcvListItemBinding) : RecyclerView.ViewHolder(binding.root){
fun onBind(data : ProfileData){
binding.user = data
}
}
마지막으로 MainActivity에서 다음과 같이 설정해주면 끝이다.
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
...
setRcv()
...
}
...
fun setRcv(){
val profileAdapter = ProfileAdapter(this)
binding.mainRcv.layoutManager = LinearLayoutManager(this)
binding.mainRcv.adapter = profileAdapter
profileAdapter.data = listOf(
ProfileData(name = "Kang", age = 26),
ProfileData(name = "Kim", age = 25)
)
profileAdapter.notifyDataSetChanged()
}
}
지금은 직접 데이터를 넣어주었으나 나중에 통신을 하게 되면 다른 방식으로 데이터를 넣어주게 될 것이다.