MixAdapter icon indicating copy to clipboard operation
MixAdapter copied to clipboard

Does not work with DiffUtil

Open dipcore opened this issue 7 years ago • 4 comments

I have child adapter which uses DiffUtil. It seems MixAdapter does not support it.

dipcore avatar Dec 27 '18 04:12 dipcore

You probably need to use registerAdapterDataObserver to sync nested adapters changes.

dipcore avatar Dec 27 '18 04:12 dipcore

I mean something like:

    /**
     * Add adapter into MixAdapter
     */
    fun addAdapter(adapter: RecyclerView.Adapter<out T>) {
        adapters.add(adapter)
        adapter.registerAdapterDataObserver(NestedAdapterDataObserver(this, adapter))
        notifyDataSetChanged()
    }

And then

class NestedAdapterDataObserver(private val parentAdapter: MixAdapter<*>?,
                                private val childAdapter: RecyclerView.Adapter<*>?) : RecyclerView.AdapterDataObserver() {

    override fun onChanged() {
        super.onChanged()
        if (parentAdapter == null) return
        parentAdapter.notifyDataSetChanged()
    }

    override fun onItemRangeChanged(positionStart: Int, itemCount: Int) {
        super.onItemRangeChanged(positionStart, itemCount)

        if (parentAdapter == null || childAdapter == null) return

        val adapterPosition = parentAdapter.getAdapterOffset(childAdapter)
        parentAdapter.notifyItemRangeChanged(adapterPosition + positionStart, itemCount)
    }

    override fun onItemRangeChanged(positionStart: Int, itemCount: Int, payload: Any?) {
        super.onItemRangeChanged(positionStart, itemCount, payload)

        if (parentAdapter == null || childAdapter == null) return

        val adapterPosition = parentAdapter.getAdapterOffset(childAdapter)
        parentAdapter.notifyItemRangeChanged(adapterPosition + positionStart, itemCount, payload)
    }

    override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
        super.onItemRangeInserted(positionStart, itemCount)

        if (parentAdapter == null || childAdapter == null) return

        val adapterPosition = parentAdapter.getAdapterOffset(childAdapter)
        parentAdapter.notifyItemRangeInserted(adapterPosition + positionStart, itemCount)
    }

    override fun onItemRangeRemoved(positionStart: Int, itemCount: Int) {
        super.onItemRangeRemoved(positionStart, itemCount)

        if (parentAdapter == null || childAdapter == null) return

        val adapterPosition = parentAdapter.getAdapterOffset(childAdapter)
        parentAdapter.notifyItemRangeRemoved(adapterPosition + positionStart, itemCount)
    }

    override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {
        super.onItemRangeMoved(fromPosition, toPosition, itemCount)

        if (parentAdapter == null || childAdapter == null) return

        val adapterPosition = parentAdapter.getAdapterOffset(childAdapter)
        parentAdapter.notifyItemMoved(adapterPosition + fromPosition, adapterPosition + toPosition)
    }
}

dipcore avatar Dec 27 '18 05:12 dipcore

I tested that solution and it seems work fine. I can do a push, if you wish.

dipcore avatar Dec 27 '18 05:12 dipcore

Sure and thanks

Jintin avatar Dec 28 '18 10:12 Jintin