利用lambda简化RecyclerView.Adapter

利用lambda简化RecyclerView.Adapter

每次出现新的列表,通常咱们会新建一个类去继承RecyclerView.Adapter而后覆写其中方法。一次两次还好,但不少次以后呢?你是否会不厌其烦?想必咱们在实际应用中也不会只有一个或两个列表,随着列表的增多,咱们写了愈来愈多的Adapter,但其中大部分代码是相同的,却不能复用,同时,我相信随着自定义的Adapter愈来愈多,管理也会越加复杂,这对咱们程序猿来讲怎么能够忍受。因此我正好利用kotlin的lambda表达式来消除咱们冗余的代码。
下面是自定义的Adapter,有了它咱们就不须要每次再作重复的劳动了。java

class ViewAdapter<T, VH : ViewHolder>(
        @LayoutRes private val layoutResId: Int,
        val data: MutableList<T> = mutableListOf()) :
        RecyclerView.Adapter<VH>(){

    constructor(
            @LayoutRes layoutResId: Int,
            data: MutableList<T> = mutableListOf(),
            @Suppress("UNCHECKED_CAST")
            clazz: Class<VH>
    ) : this(layoutResId, data) {
        this.clazz = clazz
    }

    @Suppress("UNCHECKED_CAST")
    private var clazz: Class<VH> = ViewHolder::class.java as java.lang.Class<VH>
    private var cons: Constructor<VH>? = null
    private var onItemClick: ((view: View, position: Int) -> Unit)? = null
    private lateinit var onBind: (VH, T) -> Unit

    @Suppress("UNCHECKED_CAST")
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
        val itemView = parent.context.inflate(layoutResId, parent)
        if (cons == null)
            //itemView: View, parent: ViewGroup, viewType: Int
            cons = clazz.getConstructor(View::class.java, ViewGroup::class.java, Int::class.java)
        val holder= cons!!.newInstance(itemView, parent, viewType)
        itemView.setOnClickListener {
            onItemClick?.invoke(it, holder.layoutPosition)
        }
        return holder
    }

    override fun onBindViewHolder(holder: VH, position: Int) {
        onBind(holder, data[position])
    }

    override fun getItemCount(): Int {
        return data.size
    }

    fun setOnBindListener(listener: (VH, T) -> Unit) {
        this.onBind = listener
    }

    fun setOnItemClickListener(listener: (view: View, position: Int) -> Unit) {
        this.onItemClick = listener
    }

    fun replaceAll(list: List<T>) {
        data.clear()
        data.addAll(0, list)
        notifyDataSetChanged()
    }
    
}

而后咱们就能够只经过下面的方式来设置RecyclerView的Adapter了ide

private lateinit var adapter: ViewAdapter<WeekLesson, ViewHolder>


        adapter = ViewAdapter(R.layout.class_schedule_item)
        adapter.setOnBindListener { viewHolder, classItem ->
           //Use your viewHolder
        }
        adapter.setOnItemClickListener { view, position -> 
            
        }
        recyclerView.layoutManager = LinearLayoutManager(context)
        recyclerView.adapter = adapter

这里须要注意的是setOnItemClickListener并非必须的,而setOnBindListener则是必须的,由于要在onBindViewHolder的时候要回调。
ViewHolder须要实现这样一个构造参数(itemView: View, parent: ViewGroup, viewType: Int)第一个参数是每一项的View,第二个参数在这里即为RecyclerView的父布局,第三个参数为你本身定义的ViewType。
data能够经过adapter.data访问,咱们能够在建立Adapter的时候传入数据集合,也能够在建立以后再更新布局

而后就能够开开心心的写代码了,不再用重复那些枯燥的操做啦。另外还有一种方式,就是经过自定义Android Studio模板代码的方式让IDE来帮咱们自动建立并完成一些重复代码。this

相关文章
相关标签/搜索