RecyclerView通用Adapter适配器,Kotlin

2018-07-23  本文已影响0人  Jason_Samuel

每次遇到项目中简单的列表都需要写一遍适配器岂不是很麻烦,这次通过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函数定义。

上一篇下一篇

猜你喜欢

热点阅读