web-dev-qa-db-ja.com

RecyclerView:ビューが作成された直後に最後に表示されたアイテムを検索します

次の方法で問題が発生します。

_int firstVisibleItemPosition = gridLayoutManager.findFirstVisibleItemPosition();
int lastVisibleItemPosition = gridLayoutManager.findLastVisibleItemPosition();
_

私の目標:ユーザーが表示したアイテムに関する分析データを保存します。

これを行うために、2つの異なるシナリオでこのメソッドを呼び出しています。

  • スクロールが「アイドル」状態になるたびに、表示されているアイテムを確認します。その場合、期待されるインデックスを取得しています。

  • RecyclerViewがユーザーに「表示」されたとき。それが問題の始まりです。 recylcerViewを含むフラグメントがonResume()に渡されたときに、findLastVisibleItemPosition()を呼び出すと、表示されているアイテムが返されると思います。 ただし、その場合は-1を返します。フラグメント/アクティビティのライフサイクルに関連するrecyclerView +アダプタの内部アイテムの初期化の非同期ロードと関係があると思います。

このコードを数ミリ秒延期することにより、findLastVisibleItemPosition()は適切なインデックスを返します。しかし、ハンドラー+遅延ランナブルを使用してハードコーディングを延期したくありません。遅延ランナブルをスケジュールすることは、私が本当にやりたいことの回避策であるためです。その中の足..

だから私の質問は基本的に:

  • recyclerViewが画面に足を踏み入れた子アイテムのすべての初期化/測定/膨張と描画を完了したことをどのように検出できますか? (ユーザーとの対話の前に..)。

  • リサイクラービュー内のどのアイテムが実際に画面に表示されているかを正確に知るための信頼できるグッドプラクティスの方法はありますか?

12
Tal Kanel

構成の変更はどうですか?ユーザーが画面の向きを変更すると、表示されるアイテムも変更されます。実際、表示されるアイテムは、RecyclerViewの状態、ロードされたデータ、スクロール位置、および現在の画面構成に応じて絶えず変化しています。

おそらくできる最善のことは、ItemDecorationが画面に再描画されるたびに呼び出されるRecyclerViewインターフェイスを実装することにより、表示されているアイテムのスーパーセットを常に追跡するクラスを作成することです。 、およびこのコンポーネントに定期的に統計を送信させます。構成の変更時に(状態を保持して)新しいRecyclerViewインスタンスに再アタッチします。

したがって、たとえば、このコンポーネントは、表示される最小位置と最大位置を追跡できます。最初は両方とも-1になります。次に、データが読み込まれ、最初のアイテムが画面に表示された後、ItemDecorationが再度呼び出され、最初の表示アイテムの位置が0になり、最後の表示アイテムの位置がNになります。スクロール後、値再び変わります。スーパーセットを取得するには、FirstVisibleItemPositionの最小値とLastVisibleItemPositionの最大値のみを保持します。変更なしでX秒後、またはユーザーがアクティビティから戻った場合は、これらの番号を記録して送信します。

1
BladeCoder

OnChildAttachListener を使用して、リサイクル業者が新しいホルダーを接続したことを検出します。正しいアナリティを送信するために遅延メカニズムを使用します(\ハードコードされた遅延ではなく、次のようなものです:

...
public void run(){
  removeCallbacks()
  postDelay(sendAnalytics(correctInformation),25);
}

25msの遅延は、onResumeに任意にアタッチするよりも信頼性が高くなります。

0
EE66