[Android] RecyclerView의 ListAdapter를 viewBinding과 함께 사용하는 방법
소개
RecyclerView 에서 ViewBinding 과 ListAdapter 를 조합해 사용하는 방법에 대해 조사했으므로 정리합니다.
표시할 데이터 선언
소개 User라는 firstName과 lastName, age를 가진 데이터 클래스를 정의합니다.
이번에는 이 User 에 정의한 데이터를 RecyclerView 로 표시할 수 있도록 합니다.
data class User(val firstName: String, val lastName: String, val age: Int) {
val id = UUID.randomUUID().toString()
}
표시할 View 선언
RecyclerView에 표시 할 View를 선언하기 전에 buildFeatures에서 viewBinding을 true로 설정하십시오. 이제 viewBinding이 활성화되어 viewBinding을 사용하여 View를 생성할 수 있습니다.
android {
︙省略
buildFeatures {
viewBinding true
}
︙省略
}
이번에는 View를 layout_user_item.xml이라는 파일에 정의합니다.
아래와 같이 View 로서 firstName 이나 lastName, age 를 표시할 수 있도록 해 둡니다.
<?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="wrap_content"
android:layout_margin="8dp"
android:background="#eeeeee"
android:padding="8dp">
<TextView
android:id="@+id/age_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="64sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/first_name_text_view"
app:layout_constraintTop_toTopOf="parent"
tools:text="100" />
<TextView
android:id="@+id/first_name_text_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="32sp"
app:layout_constraintBottom_toTopOf="@id/last_name_text_view"
app:layout_constraintEnd_toStartOf="@id/age_text_view"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="FIRST NAME" />
<TextView
android:id="@+id/last_name_text_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="32sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/age_text_view"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/first_name_text_view"
tools:text="LAST NAME" />
</androidx.constraintlayout.widget.ConstraintLayout>
디스플레이를 제어하는 어댑터 만들기
그런 다음 RecyclerView의 표시를 제어하는 RecyclerView.Adapter를 만듭니다. 이전에는 RecyclerView.Adapter 를 처음부터 구현할 필요가 꽤 힘들었습니다만 지금은 ListAdapter 라고 하는 RecyclerViewAdapter 의 구현을 편하게 해 주는 클래스가 공식적으로 제공되고 있습니다.
List Adapter 에는 다음의 특징이 있어 메리트가 있는 어댑터입니다만 다음과 같이 구현합니다.
소개 User라는 firstName과 lastName, age를 가진 데이터 클래스를 정의합니다.
이번에는 이 User 에 정의한 데이터를 RecyclerView 로 표시할 수 있도록 합니다.
data class User(val firstName: String, val lastName: String, val age: Int) {
val id = UUID.randomUUID().toString()
}
표시할 View 선언
RecyclerView에 표시 할 View를 선언하기 전에 buildFeatures에서 viewBinding을 true로 설정하십시오. 이제 viewBinding이 활성화되어 viewBinding을 사용하여 View를 생성할 수 있습니다.
android {
︙省略
buildFeatures {
viewBinding true
}
︙省略
}
이번에는 View를 layout_user_item.xml이라는 파일에 정의합니다.
아래와 같이 View 로서 firstName 이나 lastName, age 를 표시할 수 있도록 해 둡니다.
<?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="wrap_content"
android:layout_margin="8dp"
android:background="#eeeeee"
android:padding="8dp">
<TextView
android:id="@+id/age_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="64sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/first_name_text_view"
app:layout_constraintTop_toTopOf="parent"
tools:text="100" />
<TextView
android:id="@+id/first_name_text_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="32sp"
app:layout_constraintBottom_toTopOf="@id/last_name_text_view"
app:layout_constraintEnd_toStartOf="@id/age_text_view"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="FIRST NAME" />
<TextView
android:id="@+id/last_name_text_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="32sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/age_text_view"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/first_name_text_view"
tools:text="LAST NAME" />
</androidx.constraintlayout.widget.ConstraintLayout>
디스플레이를 제어하는 어댑터 만들기
그런 다음 RecyclerView의 표시를 제어하는 RecyclerView.Adapter를 만듭니다. 이전에는 RecyclerView.Adapter 를 처음부터 구현할 필요가 꽤 힘들었습니다만 지금은 ListAdapter 라고 하는 RecyclerViewAdapter 의 구현을 편하게 해 주는 클래스가 공식적으로 제공되고 있습니다.
List Adapter 에는 다음의 특징이 있어 메리트가 있는 어댑터입니다만 다음과 같이 구현합니다.
android {
︙省略
buildFeatures {
viewBinding true
}
︙省略
}
<?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="wrap_content"
android:layout_margin="8dp"
android:background="#eeeeee"
android:padding="8dp">
<TextView
android:id="@+id/age_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="64sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/first_name_text_view"
app:layout_constraintTop_toTopOf="parent"
tools:text="100" />
<TextView
android:id="@+id/first_name_text_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="32sp"
app:layout_constraintBottom_toTopOf="@id/last_name_text_view"
app:layout_constraintEnd_toStartOf="@id/age_text_view"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="FIRST NAME" />
<TextView
android:id="@+id/last_name_text_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="32sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/age_text_view"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/first_name_text_view"
tools:text="LAST NAME" />
</androidx.constraintlayout.widget.ConstraintLayout>
그런 다음 RecyclerView의 표시를 제어하는 RecyclerView.Adapter를 만듭니다. 이전에는 RecyclerView.Adapter 를 처음부터 구현할 필요가 꽤 힘들었습니다만 지금은 ListAdapter 라고 하는 RecyclerViewAdapter 의 구현을 편하게 해 주는 클래스가 공식적으로 제공되고 있습니다.
List Adapter 에는 다음의 특징이 있어 메리트가 있는 어댑터입니다만 다음과 같이 구현합니다.
/**
* ListAdapter<A: Object, B: RecyclerView.ViewHolder>(C: DiffUtils.ItemCallback<A>) を継承する
* 今回は User を表示するので、User を表示するための View を保持した ViewHolder と User の差分を比較するための ItemCallback をセットしてやります。
*
* - A:Object には表示するデータを保持するクラスをセットする
* - B:RecyclerView.ViewHolder には表示する View を保持する ViewHolder をセットする
* - C:DiffUtils.ItemCallback<A> には A:Object の差分確認方法を実装した ItemCallback をセットする
*/
class UserListAdapter : ListAdapter<User, UserItemViewHolder>(DIFF_UTIL_ITEM_CALLBACK) {
// ここで View を生成する、生成した View は ViewHolder に格納して、戻り値として返す
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserItemViewHolder {
val view = LayoutUserItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return UserItemViewHolder(view)
}
// その位置の User を取得し、ViewHolder を通じて View に User 情報をセットする
override fun onBindViewHolder(holderUser: UserItemViewHolder, position: Int) {
holderUser.bind(getItem(position))
}
}
/**
* 生成した View を保持する、 bind で User を View に反映させる
*/
class UserItemViewHolder(
private val binding: LayoutUserItemBinding
) : RecyclerView.ViewHolder(binding.root) {
fun bind(user: User) {
binding.firstNameTextView.text = user.firstName
binding.lastNameTextView.text = user.lastName
binding.ageTextView.text = user.age.toString()
}
}
/**
* User の差分確認する
*/
val DIFF_UTIL_ITEM_CALLBACK = object : DiffUtil.ItemCallback<User>() {
// 渡されたデータが同じ値であるか確認をする
override fun areContentsTheSame(oldItem: User, newItem: User): Boolean {
return oldItem == newItem
}
// 渡されたデータが同じ項目であるか確認する
override fun areItemsTheSame(oldItem: User, newItem: User): Boolean {
return oldItem.id == newItem.id
}
}
RecyclerView에 데이터 표시
표시하는 데이터, 표시하는 View, 표시를 제어하는 어댑터가 완성되었으므로,
나머지는 RecyclerView 를 정의해, 작성한 ListAdapter 를 세트 하면 OK입니다.
그리고 ListAdapter 의 submitList 를 호출하면 세트 한 데이터가 RecyclerView 에 표시됩니다.
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private val listAdapter = UserListAdapter()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.recyclerView.adapter = listAdapter
binding.recyclerView.layoutManager = LinearLayoutManager(applicationContext, RecyclerView.VERTICAL, false)
listAdapter.submitList(
listOf(
User("あいざわ", "かずき", 29),
User("ふじくら", "まさひろ", 52),
User("よしずみ", "ひろゆき", 54),
User("ほりのうち", "しんいち", 40),
User("はすぬま", "よしろう", 37),
User("はなわ", "のぶお", 38),
User("おじま", "おじま", 31),
User("しんざき", "くにひと", 35)
)
)
}
}
<?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">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
결론
이전에는 RecyclerView 를 구현한 코드를 기술하면 꽤 힘든 이미지였지만,
ViewBinding 과 ListAdapter 를 조합해 사용하는 것으로 꽤 스마트한 구현이 되네요.
Android 공식 라이브러리에서 여기까지 할 수 있게 되어 있는 것은 감동이군요.
현재의 Android 개발에서는 Epoxy 나 Groupie 등의 라이브러리가 자주 사용된다고 생각합니다만,
ListAdapter 가 여기까지 간단하게 사용할 수 있게 되면 이 종류의 라이브러리를 사용하는 메리트는 희미해져 네요. 개인적으로는 Epoxy에 시달리는 경우가 많기 때문에 공식 라이브러리만으로 구현할 수 있는 미래가 오기를 바랍니다.
Reference
이 문제에 관하여([Android] RecyclerView의 ListAdapter를 viewBinding과 함께 사용하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/kaleidot725/items/63a900059e5e5c615c88
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private val listAdapter = UserListAdapter()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.recyclerView.adapter = listAdapter
binding.recyclerView.layoutManager = LinearLayoutManager(applicationContext, RecyclerView.VERTICAL, false)
listAdapter.submitList(
listOf(
User("あいざわ", "かずき", 29),
User("ふじくら", "まさひろ", 52),
User("よしずみ", "ひろゆき", 54),
User("ほりのうち", "しんいち", 40),
User("はすぬま", "よしろう", 37),
User("はなわ", "のぶお", 38),
User("おじま", "おじま", 31),
User("しんざき", "くにひと", 35)
)
)
}
}
<?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">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
이전에는 RecyclerView 를 구현한 코드를 기술하면 꽤 힘든 이미지였지만,
ViewBinding 과 ListAdapter 를 조합해 사용하는 것으로 꽤 스마트한 구현이 되네요.
Android 공식 라이브러리에서 여기까지 할 수 있게 되어 있는 것은 감동이군요.
현재의 Android 개발에서는 Epoxy 나 Groupie 등의 라이브러리가 자주 사용된다고 생각합니다만,
ListAdapter 가 여기까지 간단하게 사용할 수 있게 되면 이 종류의 라이브러리를 사용하는 메리트는 희미해져 네요. 개인적으로는 Epoxy에 시달리는 경우가 많기 때문에 공식 라이브러리만으로 구현할 수 있는 미래가 오기를 바랍니다.
Reference
이 문제에 관하여([Android] RecyclerView의 ListAdapter를 viewBinding과 함께 사용하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/kaleidot725/items/63a900059e5e5c615c88텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)