Kotlin 寫一個通用Adapter (二)

說在前面

上次寫了一個通用adapter,用的過程當中,發現仍是沒那麼方便,每次數據綁定的時候都要強轉一次,bindView時也不夠簡潔,經過進一步學習kotlin,進行了優化,性能的話,單看兩者沒有多大區別,主要是在寫法的簡潔度上作出了改善,先放出代碼bash

/**
 * 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
        }
    }

}
複製代碼

使用方法以下ide

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
    }
複製代碼
相關文章
相關標籤/搜索