MVVM e seleção de itens no adaptador - Adaptador básico

Então, finalmente cheguei ao ponto culminante da minha ideia com uma biblioteca que inclui a lógica para selecionar itens de uma lista em um adaptador. Depois de uma solução independente de plataforma e uma biblioteca baseada em LiveData , escrevi algo para ajudá-lo a vincular tudo isso de forma rápida e fácil a um adaptador para reduzir o código geral.



Interface SelectingListAdapter



Vamos começar com uma interface SelectingListAdapter simples que adicionei para um adaptador com uma lista linear regular. Na minha experiência, algo em torno de 90-95% dos adaptadores são vendidos nesta forma.



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


Nada complicado - apenas atualizando a lista de itens. E, na minha opinião, não será difícil adicionar esta interface à lista das implementadas em seu adaptador. Pelo que? Ser capaz de usar os dois métodos de extensão, que mencionarei a seguir:



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


O método se observeItemsChangeinscreve nas alterações da lista de itens em LiveDataSource.



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


O método observeSelectionChangejá subscreve mudanças na seleção de itens. Aqui, há apenas uma notificação de que o elemento precisa ser atualizado. Verificar se este item já está selecionado será descrito abaixo.



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


Bem, se você deseja chamar os dois métodos ao mesmo tempo, existe observeAllChangesum que o fará em uma linha.



Classe BaseSelectingListAdapter



, 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'.




:



  • SelectionManager - GitHub
  • LiveSource - GitHub
  • SelectingAdapter - GitHub


Links no 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