web-dev-qa-db-ja.com

ListAdapter submitList()-最初にスクロールする方法

RecyclerViewとListAdapterに問題があります。

APIを介して、古いものから新しいものへと昇順でアイテムを受け取ります。

次に、submitList(items)メソッドを呼び出して、リストを更新しています。

ただし、すべてが非同期であるため、最初のアイテムを受け取った後、RecyclerViewは最初に受け取って表示したアイテムの位置に留まります。 ListAdapterクラスでは、submitList()メソッドが完了したときにコールバックがないため、追加された新しい項目の1つを更新した後にスクロールする方法が見つかりません。

ListAdapterが更新されたときにインターセプトする方法はありますか?

20
gbaccetta

ListAdapterに固有ではありませんが、それでも機能するはずです。

adapter.registerAdapterDataObserver(RecyclerView.AdapterDataObserver) を使用し、関連するonItemXXXメソッドをオーバーライドして、RecyclerViewに任意の位置までスクロールするように指示します。

例として:

    adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
        override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
            (recycler_view.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(positionStart, 0)
        }
    })
10
David Liu

オーバーライドするメソッドが呼び出されます:

public void onCurrentListChanged(List<T> previousList, List<T> currentList)

documentation のように:

現在のListが更新されたときに呼び出されます。


ListAdapterのインラインドキュメントは次のとおりです。

このクラスは、AsyncListDifferの便利なラッパーであり、アイテムのアクセスとカウントのためのアダプタの一般的なデフォルト動作を実装します。

そして後でそれは読む:

アダプターの動作をより詳細に制御したい、または特定の基本クラスを提供したい上級ユーザーは、diffイベントからアダプターの位置へのカスタムマッピングを提供するAsyncListDifferを参照する必要があります。

つまり、AsyncListDifferのカスタム実装と組み合わせて、通常のRecyclerView.Adapterを拡張する必要があります。 ListAdapterではありません(これは、便利なラッパーであり、前述の基本的な機能を備えています)。

ListAdapterクラスをそのテンプレートとして使用できますが(拡張ではなく、手掛かりです)、結果のクラスを拡張して再利用できます。そうしないと、必要なコールバックを制御する機会がありません。

3
Martin Zeitler

ListAdapterソースコードを確認しましたが、 onCurrentListChanged メソッドがあることがわかりました。

カスタムアダプタでそれをオーバーライドするだけです。リスナーにアダプターを渡してイベントをキャッチし、RecyclerViewを最初までスクロールすることもできます。

あなたのアダプター:

typealias ListChangeListener = () -> Unit

class Adapter(private val listChangeListener: ListChangeListener) : ListAdapter<Item, Adapter.ViewHolder>(Callback) {

    override fun onCurrentListChanged(previousList: List<Item>, currentList: List<Item>) {
        super.onCurrentListChanged(previousList, currentList)

        // Call your listener here
        listChangeListener()
    }

    // Other methods and ViewHolder class
}

アクティビティまたはフラグメントでアダプタを作成します。

recyclerView.adapter = Adapter { recyclerView.scrollToPosition(0) }
0
Anton Holovin