はじめに
RecyclerViewを書くたびに似たような記載するのが嫌になったので、いつも書くコードをまとめた基底クラスを作りました。
RecyclerView.ViewHolder
基底クラス
ViewHolderの方の基底クラス
Viewの作成を省略できるようにしています
BaseRecyclerViewHolder.kt
abstract class BaseRecyclerViewHolder<T>(view: View) : RecyclerView.ViewHolder(view) {
// viewを更新するときの処理
abstract fun bind(data: T)
companion object {
// ViewHolderの作成のテンプレート
inline fun <reified T, VH : BaseRecyclerViewHolder<T>> create(
parent: ViewGroup,
layoutResId: Int,
createViewHolder: (View) -> VH
): VH {
val view = LayoutInflater.from(parent.context).inflate(layoutResId, parent, false)
return createViewHolder(view).apply {
itemView.tag = this
}
}
}
}
使い方
RecyclerListCell
data class CellData(val title: String)
class RecyclerListCell(view: View) : BaseRecyclerViewHolder<CellData>(view) {
private val title = view.findViewById<TextView>(R.id.text_title)
override fun bind(data: CellData) {
title.text = data.title
}
companion object {
// Adapterの方でViewHolderを作る時に呼び出す
fun create(parent: ViewGroup): RecyclerListCell =
create(parent, R.layout.title_cell, ::RecyclerListCell)
}
}
RecyclerView.Adapter
基底クラス
Adapterの方の基底クラス
いつも使う機能だけを定義
BaseRecyclerViewAdapter.kt
abstract class BaseRecyclerViewAdapter<T> : RecyclerView.Adapter<BaseRecyclerViewHolder<T>>() {
abstract val dataList: MutableList<T>
protected abstract fun bindViewHolder(holder: VH, item: T)
// 外から更新する際に呼び出す
fun dataSetChange(newDataList: List<T>) {
dataList.clear()
dataList.addAll(newDataList)
notifyDataSetChanged()
}
override fun onBindViewHolder(holder: BaseRecyclerViewHolder<T>, position: Int) {
bindViewHolder(holder, dataList[position])
}
override fun getItemCount() = dataList.size
}
使い方
RecyclerListAdapter
class RecyclerListAdapter(
override val dataList: MutableList<CellData>
) : BaseRecyclerViewAdapter<CellData>() {
override fun bindViewHolder(holder: BaseRecyclerViewHolder<CellData>, item: CellData) {
holder.bind(item)
}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): BaseRecyclerViewHolder<CellData> =
RecyclerListCell.create(parent)
}