0

I need to swap two adapters inside the ConcatAdapter but the list of adapters that is returned by getAdapters() is immutable and won't let me use the java.util.Collections utility.

So far what I've tried was to turn that list into a mutable list, swap the items and set the list back but it's ugly to look at since I'm doing this inside the TouchHelper's callback.

Would copying the class from the source and make that list mutable instead work? Are there any better solutions?

1 Answers1

0

I tried to do some hacky stuff with reflection, the ConcatAdapter class doesn't hold a reference to the underlying adapters but there's a ConcatAdapterController field (which class is private) that has a mWrappers field which is basically the one returned by getAdapters()

Anyway here's the code I've used and it's working fine

val controllerClass = Class.forName("androidx.recyclerview.widget.ConcatAdapterController")
    val controllerField = ConcatAdapter::class.java.declaredFields.find { it.name == "mController" }?.apply {
        this.isAccessible = true
    }
    val controller = controllerField?.get(this)
    val wrappersField = controllerClass.declaredFields.find { it.name == "mWrappers"}?.apply {
        this.isAccessible = true
    }
    val wrappers = wrappersField?.get(controller) as List<*>

    Collections.swap(wrappers, from, to)

    notifyItemMoved(from, to)