RecyclerView のパーツと機能
RecyclerView
は一部のタスク (ビューのスクロールやリサイクルなど) を内部で処理しますが、基本的には、コレクションを表示するためにヘルパー クラスを調整するマネージャーです。 RecyclerView
は、タスクを次のヘルパー クラスに委任します。
Adapter
– 項目レイアウトを拡張 (レイアウト ファイルの内容をインスタンス化) し、RecyclerView
内に表示されるビューにデータをバインドします。 アダプターは、項目クリック イベントも報告します。LayoutManager
–RecyclerView
内で項目ビューを測定して配置し、ビュー リサイクルのポリシーを管理します。ViewHolder
– ビュー参照を検索して保存します。 ビュー ホルダーは、項目ビューのクリックを検出するのにも役立ちます。ItemDecoration
– アプリが項目、ハイライト、視覚的なグループ境界間の区切り線を描画するために、特別な描画およびレイアウト オフセットを特定のビューに追加できるようにします。ItemAnimator
– 項目のアクション中、またはアダプターに対して変更が加えられた場合に実行されるアニメーションを定義します。
RecyclerView
、LayoutManager
、Adapter
の各クラスの関係を次の図に示します。
この図が示すように、LayoutManager
は、Adapter
と RecyclerView
の間の仲介者として考えることができます。 LayoutManager
は、RecyclerView
に代わって Adapter
メソッドを呼び出します。 たとえば、LayoutManager
は、RecyclerView
内の特定の項目位置に新しいビューを作成するときに、Adapter
メソッドを呼び出します。 Adapter
は、その項目のレイアウトを拡張し、その位置にあるビューへの参照をキャッシュする ViewHolder
インスタンス (表示されていません) を作成します。 LayoutManager
が Adapter
を呼び出して特定の項目をデータ セットにバインドすると、Adapter
はその項目のデータを検索し、データ セットからそれを取得して、関連付けられている項目ビューにコピーします。
アプリで RecyclerView
を使用する場合は、次のクラスの派生型を作成する必要があります。
RecyclerView.Adapter
– アプリのデータ セット (アプリに固有) から、RecyclerView
内に表示される項目ビューへのバインドを提供します。 アダプターは、RecyclerView
内の各項目ビューの位置をデータ ソース内の特定の場所に関連付ける方法を認識します。 さらに、アダプターは個々の項目ビュー内のコンテンツのレイアウトを処理し、ビューごとにビュー ホルダーを作成します。 アダプターは、項目ビューによって検出された項目クリック イベントも報告します。RecyclerView.ViewHolder
– リソース検索が不必要に繰り返されないように、項目レイアウト ファイル内のビューへの参照をキャッシュします。 また、ビュー ホルダーは、ユーザーがビュー ホルダーに関連付けられた項目ビューをタップしたときに項目クリック イベントがアダプターに転送されるように配置します。RecyclerView.LayoutManager
–RecyclerView
内に項目を配置します。 いくつかの事前定義されたレイアウト マネージャーの 1 つを使用することも、独自のカスタム レイアウト マネージャーを実装することもできます。RecyclerView
はレイアウト ポリシーをレイアウト マネージャーに委任するため、アプリに大幅な変更を加えることなく、別のレイアウト マネージャーをプラグインできます。
また、必要に応じて次のクラスを拡張して、アプリ内の RecyclerView
の外観を変更することもできます。
RecyclerView.ItemDecoration
RecyclerView.ItemAnimator
ItemDecoration
と ItemAnimator
を拡張しない場合、RecyclerView
は既定の実装を使用します。 このガイドでは、ItemDecoration
と ItemAnimator
のカスタム クラスの作成方法については説明しません。これらのクラスの詳細については、「RecyclerView.ItemDecoration」と「RecyclerView.ItemAnimator」を参照してください。
ビューのリサイクルのしくみ
RecyclerView
では、データ ソース内のすべての項目に項目ビューが割り当てられるわけではありません。 代わりに、画面に収まる数の項目ビューのみが割り当てられ、ユーザーがスクロールするときにそれらの項目レイアウトが再利用されます。 ビューが最初に画面外にスクロールすると、次の図に示すリサイクル プロセスが実行されます。
ビューが画面外にスクロールして見えなくなると、"スクラップ ビュー" になります。
スクラップ ビューはプールに配置され、"リサイクル ビュー" になります。 このプールは、同じ種類のデータを表示するビューのキャッシュです。
新しい項目が表示される場合、再利用のためにリサイクル プールからビューが取得されます。 このビューは、表示される前にアダプターによって再バインドされる必要があるため、"ダーティ ビュー" と呼ばれます。
ダーティ ビューはリサイクルされます。アダプターは、表示する次の項目のデータを検索し、この項目のビューにこのデータをコピーします。 これらのビューの参照は、リサイクルされたビューに関連付けられているビュー ホルダーから取得されます。
リサイクルされたビューは、これから画面上に表示される
RecyclerView
内の項目のリストに追加されます。ユーザーが
RecyclerView
をリスト内の次の項目までスクロールすると、リサイクルされたビューが画面上に表示されます。 一方、別のビューが画面外にスクロールし、上記の手順に従ってリサイクルされます。
項目ビューの再利用に加えて、RecyclerView
はもう 1 つの効率の最適化であるビュー ホルダーも使用します。 "ビュー ホルダー"は、ビュー参照をキャッシュする単純なクラスです。 アダプターが項目レイアウト ファイルを拡張するたびに、対応するビュー ホルダーも作成されます。 ビュー ホルダーは FindViewById
を使用して、拡張された項目レイアウト ファイル内のビューへの参照を取得します。 これらの参照は、新しいデータを表示するためにレイアウトがリサイクルされるたびに新しいデータをビューに読み込むのに使用されます。
レイアウト マネージャー
レイアウト マネージャーは、RecyclerView
表示内での項目の配置を担当します。プレゼンテーションの種類 (リストまたはグリッド)、向き (項目が垂直方向または水平方向のどちらで表示されるか)、項目をどの向きで表示するか (通常の順序または逆の順序で) を決定します。 レイアウト マネージャーは、RecycleView 表示内の各項目のサイズと位置を計算する役割も担います。
レイアウト マネージャーには他にも目的があります。それは、ユーザーに表示されなくなった項目ビューをいつリサイクルするかについてのポリシーを決定することです。 レイアウト マネージャーはどのビューが表示されているか (どのビューが表示されていないか) を認識しているため、ビューをいつリサイクルできるかを決定するのに最適な立場にあります。 ビューをリサイクルするため、「ビューのリサイクルのしくみ」で前述したように、レイアウト マネージャーは通常、アダプターを呼び出して、リサイクルされたビューの内容を別のデータに置き換えます。
RecyclerView.LayoutManager
を拡張して独自のレイアウト マネージャーを作成することも、事前定義されたレイアウト マネージャーを使用することもできます。 RecyclerView
には、次の定義済みのレイアウト マネージャーが用意されています。
LinearLayoutManager
– 垂直方向にスクロールできる列、または水平方向にスクロールできる行に項目を配置します。GridLayoutManager
– グリッドに項目を表示します。StaggeredGridLayoutManager
– 一部の項目の高さと幅が異なる、千鳥状のグリッドに項目を表示します。
レイアウト マネージャーを指定するには、選択したレイアウト マネージャーをインスタンス化し、それを SetLayoutManager
メソッドに渡します。 レイアウト マネージャーを指定する "必要" があることに注意してください。RecyclerView
では、既定で定義済みのレイアウト マネージャーは選択されません。
レイアウト マネージャーの詳細については、RecyclerView.LayoutManager クラスのリファレンスを参照してください。
ビュー ホルダー
ビュー ホルダーは、ビュー参照をキャッシュするために定義するクラスです。 アダプターはこれらのビュー参照を使用して、各ビューをそのコンテンツにバインドします。 RecyclerView
内のすべての項目には、その項目のビュー参照をキャッシュするビュー ホルダー インスタンスが関連付けられています。 ビュー ホルダーを作成するには、次の手順に従って、項目ごとに正確なビューのセットを保持するクラスを定義します。
- サブクラス
RecyclerView.ViewHolder
。 - ビュー参照を検索して保存するコンストラクターを実装します。
- アダプターがこれらの参照にアクセスするために使用できるプロパティを実装します。
ViewHolder
実装の詳細な例は、「基本的な RecyclerView の例」に示されています。
RecyclerView.ViewHolder
の詳細については、RecyclerView.ViewHolder クラスのリファレンスを参照してください。
アダプター
RecyclerView
統合コードの "重労働" のほとんどは、アダプターで行われます。 RecyclerView
では、データ ソースにアクセスし、各項目にデータ ソースのコンテンツを設定するために、RecyclerView.Adapter
から派生したアダプターを提供する必要があります。
データ ソースはアプリ固有であるため、データにアクセスする方法を理解するアダプター機能を実装する必要があります。 アダプターによってデータ ソースから情報が抽出され、それが RecyclerView
コレクションの各項目に読み込まれます。
次の図は、アダプターがビュー ホルダーを介してデータ ソース内のコンテンツを RecyclerView
の各行項目内の個々のビューにマップする方法を示しています。
アダプターは RecyclerView
の各行に特定の行項目のデーを読み込みます。 たとえば、行位置 P の場合、アダプターは、データ ソース内の位置 P に関連付けられているデータを検索し、RecyclerView
コレクション内の位置 P にある行項目にこのデータをコピーします。
たとえば、上の図では、アダプターはビュー ホルダーを使用してその位置にある ImageView
と TextView
の参照を検索するため、ユーザーがコレクションをスクロールしてビューを再利用するときに、これらのビューに対して FindViewById
を繰り返し呼び出す必要はありません。
アダプターを実装するときは、次の RecyclerView.Adapter
メソッドをオーバーライドする必要があります。
OnCreateViewHolder
– 項目レイアウト ファイルとビュー ホルダーをインスタンス化します。OnBindViewHolder
– 指定した位置にあるデータを、指定されたビュー ホルダーに参照が保存されているビューに読み込みます。ItemCount
– データ ソース内の項目の数を返します。
レイアウト マネージャーは、RecyclerView
内に項目を配置するときにこれらのメソッドを呼び出します。
RecyclerView へのデータ変更の通知
RecyclerView
では、そのデータ ソースのコンテンツが変更されてもその表示は自動的には更新されません。データ セットに変更があった場合は、アダプターが RecyclerView
に通知する必要があります。 データセットはさまざまな方法で変更される可能性があります。たとえば、項目内のコンテンツが変更されたり、データの全体的な構造が変更されたりする可能性があります。
RecyclerView.Adapter
には、RecyclerView
が最も効率的な方法でデータ変更に応答できるように呼び出すことができるメソッドが多数用意されています。
NotifyItemChanged
– 指定した位置にある項目が変更されたことを通知します。NotifyItemRangeChanged
– 指定した位置範囲の項目が変更されたことを通知します。NotifyItemInserted
– 指定した位置の項目が新しく挿入されたことを通知します。NotifyItemRangeInserted
– 指定した位置範囲の項目が新しく挿入されたことを通知します。NotifyItemRemoved
– 指定した位置にある項目が削除されたことを通知します。NotifyItemRangeRemoved
– 指定した位置範囲の項目が削除されたことを通知します。NotifyDataSetChanged
– データ セットが変更されたことを通知します (完全な更新が強制されます)。
データ セットがどのように変更されたかを正確に把握している場合は、上記の適切なメソッドを呼び出して、最も効率的な方法で RecyclerView
を更新できます。 データ セットがどのように変更されたかが正確にわからない場合は、NotifyDataSetChanged
を呼び出すことができますが、RecyclerView
はユーザーに表示されているすべてのビューを更新する必要があるため、効率が大幅に低下します。 これらのメソッドの詳細については、「RecyclerView.Adapter」を参照してください。
次のトピック「基本的な RecyclerView の例」では、上で概説したパーツと機能の実際のコード例を示すために、サンプル アプリを実装します。