MVVM y selección de elementos en el adaptador - Adaptador básico

Entonces, finalmente llegué a la culminación de mi idea con una biblioteca que incluye la lógica para seleccionar elementos de una lista en un adaptador. Después de una solución independiente de la plataforma y una biblioteca basada en LiveData , escribí algo para ayudarlo a vincular rápida y fácilmente todo esto a un adaptador para reducir el código general.



Interfaz SelectingListAdapter



Comencemos con una sencilla interfaz SelectingListAdapter que agregué para un adaptador con una lista lineal regular. En mi experiencia, entre el 90 y el 95% de los adaptadores se venden de esta forma.



interface SelectingListAdapter<T> {
    fun setListItems(items: ArrayList<T>)
}


Nada complicado, solo actualizando la lista de elementos. Y, en mi opinión, no será difícil agregar esta interfaz a la lista de las implementadas en su adaptador. ¿Para qué? Para poder utilizar ambos métodos de extensión, que mencionaré a continuación:



fun <T> SelectingListAdapter<T>.observeItemsChange(lifecycleOwner: LifecycleOwner,
                                                   liveDataSource: LiveDataSource<T>) {
    liveDataSource.allItems.observe(lifecycleOwner, { items -> setListItems(items) })
}


El método se observeItemsChangesuscribe a cambios en la lista de elementos en LiveDataSource.



fun RecyclerView.Adapter<*>.observeSelectionChange(lifecycleOwner: LifecycleOwner,
                                                   liveDataSource: LiveDataSource<*>) {
    liveDataSource.observeSelectionChange(lifecycleOwner) { position, _ ->
        notifyItemChanged(position)
    }
}


El método observeSelectionChangeya se suscribe a cambios en la selección de elementos. Aquí solo hay una notificación de que el elemento debe actualizarse. A continuación se describirá la verificación de si este elemento ya está seleccionado.



fun <T, TAdapter> TAdapter.observeAllChanges(lifecycleOwner: LifecycleOwner,
                                             liveDataSource: LiveDataSource<T>)
        where TAdapter : RecyclerView.Adapter<*>,
              TAdapter : SelectingListAdapter<T> {
    observeSelectionChange(lifecycleOwner, liveDataSource)
    observeItemsChange(lifecycleOwner, liveDataSource)
}


Bueno, si desea llamar a ambos métodos a la vez, hay observeAllChangesuno que lo hará en una línea.



BaseSelectingListAdapter (clase)



, LiveDataSource, . , :



abstract class BaseSelectingListAdapter<T, VH: BaseSelectingListHolder<T>> 
        : RecyclerView.Adapter<VH>(), SelectingListAdapter<T> {
    var callback: SelectingListAdapterCallback? = null
    ...
}
abstract class BaseSelectingListHolder<T>(itemView: View) : RecyclerView.ViewHolder(itemView) {
    abstract fun bindItem(item: T, isSelected: Boolean, onClick: (() -> Unit)?)
}


, SelectingListAdapterCallback.



interface SelectingListAdapterCallback {
    fun isItemSelected(position: Int): Boolean
    fun clickItem(position: Int)
}


, , , .

BaseSelectingListAdapter , LiveDataSource.



fun <T> setCallback(liveDataSource: LiveDataSource<T>) {
    callback = object : SelectingListAdapterCallback {
        override fun isItemSelected(position: Int) =
            liveDataSource.isItemSelected(position)
        override fun clickItem(position: Int) {
            liveDataSource.clickPosition(position)
        }
    }
}


BaseSelectingListAdapter — , .



    fun fullyInitialize(lifecycleOwner: LifecycleOwner,
                        liveDataSource: LiveDataSource<T>) {
        observeAllChanges(lifecycleOwner, liveDataSource)
        setCallback(liveDataSource)
    }


fullyInitialize, . . , , .



onCreateViewHolder bindItem. -, boilerplate .



class MyAdapter : BaseSelectingListAdapter<User, MyHolder>() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
        MyHolder(...)//create your holder view
}
class MyHolder(itemView: View) : BaseSelectingListHolder<User>(itemView) {
    override fun bindItem(item: User, isSelected: Boolean, onClick: (() -> Unit)?) {
        //bind your data
    }
}




, . - , , :



  1. .
  2. ( , ), SelectionManager'.




:





Enlaces en Gradle:



implementation 'ru.ircover.selectionmanager:core:1.1.0'

implementation 'ru.ircover.selectionmanager:livesource:1.0.1'

implementation 'ru.ircover.selectionmanager:selectingadapter:1.0.0'




All Articles