Android ViewDataBinding 与 RecyclerView 的结合

转载请注明出处!!!!

要想让ViewDataBinding与RecyclerView完美结合,我们首先需要封装RecyclerView.ViewHolder与RecyclerView.Adapter。

一、封装RecyclerView.ViewHolder

class BindingViewHolder(val viewBinding: T) : RecyclerView.ViewHolder(viewBinding.root)

二、封装RecyclerView. Adapter

1. BindingRecyclerViewAdapter

abstract class BindingRecyclerViewAdapter : RecyclerView.Adapter>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BindingViewHolder {
        val viewBinding = onCreateViewBinding(LayoutInflater.from(parent.context), parent, viewType, false)
        return BindingViewHolder(viewBinding)
    }

    abstract fun onCreateViewBinding(inflater: LayoutInflater, root: ViewGroup?, viewType: Int, attachToRoot: Boolean): VB

    @CallSuper
    override fun onBindViewHolder(holder: BindingViewHolder, position: Int) {
        if (holder.viewBinding is ViewDataBinding) {
            holder.viewBinding.executePendingBindings()
        }
    }
}

BindingRecyclerViewAdapter 实现了对RecyclerView.Adapter 基本封装

2. ObservableBindingRecyclerViewAdapter

abstract class ObservableBindingRecyclerViewAdapter(
        val dataList: ObservableList
) : BindingRecyclerViewAdapter() {

    private val dataListChangedCallback: DataListChangedCallback = DataListChangedCallback()

    override fun onBindViewHolder(holder: BindingViewHolder, position: Int) {
        super.onBindViewHolder(holder, position)
        onBindViewHolderViewBinding(holder, position, holder.viewBinding,
                dataList[getDataItemPosition(position)])
    }

    open fun onBindViewHolderViewBinding(holder: BindingViewHolder, position: Int,
                                         viewBinding: VB, item: E) {

    }

    open fun getDataItemPosition(listPosition: Int): Int {
        return listPosition
    }

    override fun onBindViewHolder(holder: BindingViewHolder, position: Int, payloads: MutableList) {
        super.onBindViewHolder(holder, position, payloads)
        onBindViewHolderViewBinding(holder, position,
                holder.viewBinding, dataList[getDataItemPosition(position)], payloads)
    }

    open fun onBindViewHolderViewBinding(holder: BindingViewHolder, position: Int,
                                         viewBinding: VB, item: E, payloads: MutableList) {
    }

    override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
        super.onAttachedToRecyclerView(recyclerView)
        dataList.addOnListChangedCallback(dataListChangedCallback)
    }

    override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
        super.onDetachedFromRecyclerView(recyclerView)
        dataList.removeOnListChangedCallback(dataListChangedCallback)
    }

    override fun getItemCount() = dataList.size

    private inner class DataListChangedCallback : ObservableList.OnListChangedCallback>() {

        override fun onChanged(sender: ObservableList?) {
            [email protected]()
        }

        override fun onItemRangeChanged(sender: ObservableList?, positionStart: Int, itemCount: Int) {
            [email protected](positionStart, itemCount)
        }

        override fun onItemRangeInserted(sender: ObservableList?, positionStart: Int, itemCount: Int) {
            this@ObservableBindingRecyclerViewAdapter.notifyItemRangeInserted(positionStart, itemCount)
        }

        override fun onItemRangeMoved(sender: ObservableList?, fromPosition: Int, toPosition: Int, itemCount: Int) {
            [email protected]()
        }

        override fun onItemRangeRemoved(sender: ObservableList?, positionStart: Int, itemCount: Int) {
            [email protected](positionStart, itemCount)
        }

    }

}

ObservableBindingRecyclerViewAdapter对可观察数据集合的封装。注意操作集合时要在主线程。

三、使用

class SampleListAdapter(
        private val sampleItems: ObservableList
) : ObservableBindingRecyclerViewAdapter(sampleItems) {

    override fun onCreateViewBinding(inflater: LayoutInflater, root: ViewGroup?, viewType: Int,
                                     attachToRoot: Boolean): SampleItemBinding {
        return SampleItemBinding.inflate(inflater, root, attachToRoot)
    }

    override fun onBindViewHolderViewBinding(holder: BindingViewHolder,
                                             position: Int, viewBinding: SampleItemBinding, item: SampleItem) {
        viewBinding.sampleItem = item
    }
}
viewBinding.recyclerView. ···
viewBinding.recyclerView.adapter = SampleListAdapter(sampleItems)
viewBinding.recyclerView. ···

你可能感兴趣的:(Android ViewDataBinding 与 RecyclerView 的结合)