利用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

相關文章
相關標籤/搜索