[解決済み] RecyclerView.ViewHolder - getLayoutPosition と getAdapterPosition の比較。
質問
新しいサポートライブラリのバージョン(22.x)からは
getPosition()
メソッドの
RecyclerView.ViewHolder
クラスのメソッドが非推奨となり、このトピックで紹介されているメソッドに取って代わられました。ドキュメントを読んでも違いがよくわかりません。
どなたか平易な言葉で違いを説明していただけませんか?
私は次のような使用例を持っています。アダプタに
List
を与え、さらに各リストアイテムに追加情報を関連付けたいと考えています。位置と余分のマッピングがあり、そのマッピングはホルダーが自分の位置の余分を取得し、それを使って何かできるようにするためです。ホルダーでは、どのメソッドを使用する必要がありますか?
インデックス0と1のリストアイテムが入れ替わったとき、ホルダーの位置はどうなるのでしょうか?メソッドは何を返すのですか?
どのように解決するのですか?
これは厄介な状況で、ドキュメントが十分でないのが残念です。
アダプタのコンテンツが変更されたとき (そして
notify***()
) RecyclerViewは新しいレイアウトを要求します。その瞬間から、レイアウトシステムが新しいレイアウトを計算することを決定するまで( <16 ms )、レイアウトはまだアダプタの変更を反映していないため、レイアウト位置とアダプタ位置が一致しないことがあります。
あなたの使用例では、データがアダプタの内容に関連しているため(そしてアダプタの変更と同時にデータも変更されると仮定します)、あなたは
adapterPosition
.
しかし、もしあなたが
notifyDataSetChanged()
を呼び出すと、すべてが無効になってしまうため、RecyclerViewは次のレイアウトが計算されるまでViewHolderのアダプタの位置を知ることができません。その場合
getAdapterPosition()
は
RecyclerView#NO_POSITION
(
-1
).
しかし、もしあなたが
notifyItemInserted(0)
を呼び出した場合、その
getAdapterPosition()
の位置にあった ViewHolder の
0
を返すようになります。
1
をすぐに返し始めます。つまり、粒状の通知イベントをディスパッチしている限り、常に良い状態(新しいレイアウトがまだ計算されていなくても、アダプタの位置がわかる)であることがわかります。
別の例として、ユーザがクリックしたときに何かをする場合、もし
getAdapterPosition()
が返す
NO_POSITION
を返す場合、ユーザーが何をクリックしたのかわからないので、そのクリックを無視するのが最善です(例えば、項目を調べるための安定したIDなど、他のメカニズムがない限り)。
レイアウト位置が良いときのために編集する
例えば
LinearLayoutManager
を使用していて、現在クリックされているアイテムの上の ViewHolder にアクセスしたいとします。その場合、レイアウトポジションを使用して、上のアイテムを取得する必要があります。
mRecyclerView.findViewHolderForLayoutPosition(myViewHolder.getLayoutPosition() - 1)
ユーザーが現在画面上で見ているものと一致するため、レイアウト位置を使用する必要があります。
関連
-
[解決済み] AndroidでラジオボタンにOnClickListenerを設定するには?
-
[解決済み] Gmailの3分割アニメーションシナリオの完全動作サンプル?
-
[解決済み] Androidのadb logcatでTAG名で特定のメッセージを除外する方法は?
-
[解決済み] 複数のフィルタを持つBroadcastReceiverか、複数のBroadcastReceiverか?
-
[解決済み] Android - Snackbar vs Toast - 使い方と違い。
-
[解決済み] Android StudioからADBを手動で再起動する方法
-
[解決済み] Android Lintが翻訳されていない文字列を訴えないようにする。
-
[解決済み] ブルートゥースアプリケーションのテストにアンドロイドエミュレータを使用するには?
-
[解決済み] WhatsAppでメッセージを送信する
-
[解決済み] <string> XMLで改行やタブを作るには(eclipse/android)?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] アンドロイドフラグメント onRestoreInstanceState
-
[解決済み] プログラムでソフトキーボードを開く
-
[解決済み] アンドロイドアプリのユーザーデータを消去する
-
[解決済み] これはどういうことですか?失敗 [INSTALL_FAILED_CONTAINER_ERROR]?
-
[解決済み] ArrayList<MyCustomClass>をJSONArrayに変換する。
-
[解決済み] フラグメント間の値の受け渡し方法
-
[解決済み] キャンバスに複数行のテキストを描画する
-
[解決済み] サポートライブラリのアクションバーをPreferenceActivityに追加するには?
-
[解決済み] Travis.yml ./gradlew : パーミッションが拒否されました。
-
[解決済み] RecyclerViewでクリックされた項目とその位置を取得する