Kotlin RecyclerView 萬能 adapter

說在前面

上次寫了一個通用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
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章