MVVMとアダプター内のアイテムの選択-基本アダプター

それで、私はついに、アダプターのリストからアイテムを選択するためのロジックを含むライブラリーで私のアイデアの集大成に到達しました。プラットフォームに依存しないソリューションLiveData基づくライブラリの後で、これらすべてをアダプタにすばやく簡単にリンクしてコード全体を削減するのに役立つ何かを書きました。



SelectingListAdapterインターフェース



通常の線形リストを持つアダプター用に追加した単純なSelectingListAdapterインターフェースから始めましょう。私の経験では、アダプターの90〜95%がこの形式で販売されています。



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


複雑なことは何もありません-アイテムのリストを更新するだけです。そして、私の意見では、このインターフェースをアダプターに実装されているインターフェースのリストに追加することは難しくありません。何のために?両方の拡張方法を使用できるように、次に指摘します。



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


このメソッドobserveItemsChangeは、内のアイテムのリストへの変更をサブスクライブしますLiveDataSource



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


メソッドobserveSelectionChangeは、アイテムの選択の変更をすでにサブスクライブしています。ここでは、要素を更新する必要があるという通知のみがあります。この項目がすでに選択されているかどうかの確認については、以下で説明します。



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


両方のメソッドを一度に呼び出したい場合はobserveAllChanges、1行で呼び出すメソッドがあります。



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




:





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