每次遇到项目中简单的列表都需要写一遍适配器岂不是很麻烦,这次通过Kotlin简洁的语法结构,重写了一遍通用的适配器类,它适用于简单重复的RecyclerView的Item样式,例如电话簿列表、好友列表和新闻列表等,并且不存在上下快速滑动时数据错位的现象。
先看看它的使用方法,只需要传入显示的List、Item的Layout布局和实现一个回调接口即可完成适配器的绑定。回调接口中返回的viewHolder和position分别表示,当前item的布局和当前下标。
private universalAdapter : UniversalAdapter<Room>? = null // 通用适配器
private roomList = ArrayList<Room>() // 房间列表
initRecyclerView() {
universalAdapter = UniversalAdapterK(roomList!!, R.layout.item_room, object : OnBindViewListener<RunningTime>{
override fun onItemViewBinding(viewHolder: UniversalAdapterK<RunningTime>.ViewHolder, position: Int) {
// 从List中获取当前item
val room = roomList.get(position)
// 获取当前item的布局
val itemView = viewHolder.itemView
// 给这个布局上面的文本框赋值
itemView.tv_room_name.setText(room.roomName)
// TODO 当然你也可以给这个item,或是item里面的一个按钮加上点击事件
})
recyclerview.setAdapter(universalAdapter)
}
通过以下的代码实现通用适配器的实现,Kotlin写法主要体现在了类的声明、构造函数和方法定义上。(工具类直接复制进自己项目即可)
class UniversalAdapterK<T>
(private var mDataList: ArrayList<T>, // 需要使用的数据源
private val itemLayout: Int, // 列表布局
private val onBindViewListener: OnBindViewListener<T>) // 回调接口
: RecyclerView.Adapter<UniversalAdapterK<T>.ViewHolder>() {
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): ViewHolder =
ViewHolder(LayoutInflater.from(viewGroup.context).inflate(itemLayout, viewGroup, false))
override fun onBindViewHolder(viewHolder: UniversalAdapterK<T>.ViewHolder, i: Int) =
onBindViewListener.onItemViewBinding(viewHolder, i)
override fun getItemCount(): Int = mDataList.size
/**
* 使用这个替代原来的notifyDataSetChanged
*
* @param mDataList
*/
fun refresh(mDataList: ArrayList<T>) {
this.mDataList = mDataList
notifyDataSetChanged()
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
interface OnBindViewListener<T> {
/**
* 回调每个item的view
*/
fun onItemViewBinding(viewHolder: UniversalAdapterK<T>.ViewHolder, position: Int)
}
}
关于构造函数:Kotlin支持直接在类名后面的括号中直接定义有参构造函数,类似于以前的private name = "";
加上this.name = name;
的结合。
关于方法定义:采用单行写法可以把{}
省去,替换成=
,后面跟上需要return的表达式。
关于内部类与继承:KT在声明内部类的时候,必须要加上inner
关键字,否则编译将不通过。拿以上代码里的ViewHolder内部类举例,其中类名后面的(itemView: View)
就是这个对象的构造函数,如果不写成ViewHolder(private var itemView: View)
,那么系统将会自动默认它有对外的set/get方法,也是可以在外部被调用。ViewHolder继承了RecyclerView.ViewHolder,可是父类需要子类重写一遍构造函数,那么我们括号里扔进一个itemView
,这个itemView就是前面在定义ViewHolder时传进来的itemView,可以类似于Java写法中的super(itemView)
。所以KT用一行代码就完成了:内部类声明+子类构造函数声明+调用父类构造函数+set/get函数定义。
网友评论