Jintin / MixAdapter

Compose multiple Adapter for RecyclerView in Android
https://jitpack.io/#jintin/MixAdapter
MIT License
19 stars 2 forks source link

Does not work with DiffUtil #3

Open dipcore opened 5 years ago

dipcore commented 5 years ago

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

dipcore commented 5 years ago

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

dipcore commented 5 years ago

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 commented 5 years ago

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

Jintin commented 5 years ago

Sure and thanks