上次寫了一個通用adapter,用的過程當中,發現仍是沒那麼方便,每次數據綁定的時候都要強轉一次,bindView時也不夠簡潔,經過進一步學習kotlin,進行了優化,性能的話,單看兩者沒有多大區別,主要是在寫法的簡潔度上作出了改善,先放出代碼bash
/**
* actor 晴天 create 2019/5/17
* 封裝一個kotlin下的通用adapter
*/
class KotlinDataAdapter<T> private constructor() : RecyclerView.Adapter<KotlinDataAdapter<T>.MyViewHolder>() {
//數據
private var mDatalist: ArrayList<T>? = null
//佈局id
private var mLayoutId: Int? = null
//綁定事件的lambda放發
private var addBindView: ((itemView: View, itemData: T) -> Unit)? = null
override fun onCreateViewHolder(p0: ViewGroup, p1: Int): MyViewHolder {
val view = LayoutInflater.from(p0.context).inflate(mLayoutId!!, p0, false)
return MyViewHolder(view)
}
override fun getItemCount(): Int {
return mDatalist?.size ?: -1 //左側爲null時返回-1
}
override fun onBindViewHolder(p0: MyViewHolder, p1: Int) {
addBindView?.invoke(p0.itemView, mDatalist?.get(p1)!!)
}
inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
/**
* 建造者,用來完成adapter的數據組合
*/
class Builder<B> {
private var adapter: KotlinDataAdapter<B> = KotlinDataAdapter()
/**
* 設置數據
*/
fun setData(lists: ArrayList<B>): Builder<B> {
adapter.mDatalist = lists
return this
}
/**
* 設置佈局id
*/
fun setLayoutId(layoutId: Int): Builder<B> {
adapter.mLayoutId = layoutId
return this
}
/**
* 綁定View和數據
*/
fun addBindView(itemBind: ((itemView: View, itemData: B) -> Unit)): Builder<B> {
adapter.addBindView = itemBind
return this
}
fun create(): KotlinDataAdapter<B> {
return adapter
}
}
}
複製代碼
使用方法以下ide
val adapter = KotlinDataAdapter.Builder<DeviceModel>()
.setData(deviceList)
.setLayoutId(R.layout.item_device)
.addBindView { itemView, itemData ->
itemView.tv_device_name.text = if (itemData.platform.isEmpty()) "未命名" else
}
.create()
複製代碼
看起來其實差異也不算太大哈,主要變化是在聲明的時候,採用了泛型,聲明時須要傳入指定的數據類型,再者是,以前在addBindView得時候,須要用object:來傳入對象,再在裏面實現方法,此次我使用了lambda表達式的方式,addBindView的時候就能夠直接傳入lambda表達式,從而進一步簡化了代碼,代碼其實很簡單,想要進一步瞭解的能夠搜索一下kotlin的lambda方法,和高階函數的使用函數
//綁定事件的lambda放發
private var addBindView: ((itemView: View, itemData: T) -> Unit)? = null
/**
* 綁定View和數據
*/
fun addBindView(itemBind: ((itemView: View, itemData: B) -> Unit)): Builder<B> {
adapter.addBindView = itemBind
return this
}
複製代碼