说在前面
上次写了一个通用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
}