說在前面
上次寫了一個通用adapter,用的過程中,發現還是沒那麼方便,每次資料繫結的時候都要強轉一次,bindView時也不夠簡潔,通過進一步學習kotlin,進行了優化,效能的話,單看二者沒有多大區別,主要是在寫法的簡潔度上做出了改善,先放出程式碼
/**
* 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
}
}
}
複製程式碼
使用方法如下
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
}
複製程式碼