@gordan-glavas Thanks for this tutorial! :]
I saw that the generated PersonAdapter
’s ViewHolder
finds the views inside the bind()
method:
class ViewHolder(
itemView: View
) : androidx.recyclerview.widget.RecyclerView.ViewHolder(itemView) {
fun bind(item: Person) {
itemView.findViewById<TextView>(2131165330).text = item.name
itemView.findViewById<TextView>(2131165248).text = item.address
}
}
Instead, it’d better to find the views only once, when the ViewHolder
is created, so I changed the AdapterCodeBuilder
like this:
private fun TypeSpec.Builder.addViewHolderType(): TypeSpec.Builder = addType(
...
.addSuperclassConstructorParameter("itemView")
.addProperties()
.addBindingMethod()
.build()
)
private fun TypeSpec.Builder.addProperties(): TypeSpec.Builder = addProperties(
data.viewHolderBindingData.map {
PropertySpec.builder(it.fieldName, textViewClassName)
.addModifiers(KModifier.PRIVATE)
.initializer(
"itemView.findViewById<%T>(%L)",
textViewClassName,
it.viewId
)
.build()
}
)
private fun TypeSpec.Builder.addBindingMethod(): TypeSpec.Builder = addFunction(
FunSpec.builder("bind")
.addParameter("item", modelClassName)
.apply {
data.viewHolderBindingData.forEach {
addStatement("%L.text = item.%L", it.fieldName, it.fieldName)
}
}
.build()
)
Now, PersonAdapter
’s ViewHolder
looks like this:
class ViewHolder(
itemView: View
) : androidx.recyclerview.widget.RecyclerView.ViewHolder(itemView) {
private val name: TextView = itemView.findViewById<TextView>(2131165330)
private val address: TextView = itemView.findViewById<TextView>(2131165248)
fun bind(item: Person) {
name.text = item.name
address.text = item.address
}
}