これはトリッキーな状況です。ドキュメントが十分でないことを残念に思います。
アダプタの内容が変更されると(そしてあなたが呼び出すとnotify***()
)、RecyclerViewは新しいレイアウトを要求します。その瞬間から、レイアウトシステムが新しいレイアウトの計算を決定するまで(<16 ms)、レイアウトはまだアダプターの変更を反映していないため、レイアウトの位置とアダプターの位置が一致しない場合があります。
ユースケースでは、データはアダプターの内容に関連しているため(アダプターの変更と同時にデータが変更されると想定しています)、を使用する必要がありますadapterPosition
。
ただし、を呼び出す場合はnotifyDataSetChanged()
、すべてが無効になるため、次のレイアウトが計算されるまで、RecyclerViewはViewHolderのアダプター位置を認識しないことに注意してください。その場合、getAdapterPosition()
はRecyclerView#NO_POSITION
(-1
)を返します。
ただしnotifyItemInserted(0)
、getAdapterPosition()
を呼び出した場合、以前はその位置にあったViewHolderのがすぐに0
戻り始め1
ます。きめ細かい通知イベントをディスパッチしている限り、常に良好な状態です(新しいレイアウトがまだ計算されていなくても、アダプターの位置はわかっています)。
別の例として、ユーザーのクリックで何かをしている場合、getAdapterPosition()
returnsの場合NO_POSITION
、どのユーザーがクリックしたかわからないため、そのクリックを無視するのが最善です(アイテムを検索するための安定したIDなど、他のメカニズムがない場合)。
レイアウト位置が適切な場合の編集
LinearLayoutManager
現在クリックされているアイテムの上にあるViewHolderを使用していて、アクセスしたいとします。その場合、上記のアイテムを取得するには、レイアウト位置を使用する必要があります。
mRecyclerView.findViewHolderForLayoutPosition(myViewHolder.getLayoutPosition() - 1)
レイアウト位置は、ユーザーが現在画面に表示しているものと一致するため、使用する必要があります。