AndroidX TV ライブラリ

ほとんどの AndroidX ライブラリは Android TV で使用できます。ViewModel などのアーキテクチャ コンポーネントを使用してライフサイクル対応 UI データを管理できます。また、Room を使用すると、モバイルの場合と同様にローカル SQLite データベースを簡単に操作できます。ただし、Android TV 専用の機能をサポートする TV 固有のライブラリもあります。これらのライブラリには次のものがあります。

  • Leanback ライブラリには、Android TV アプリの作成を簡素化する UI テンプレートが用意されています。
  • Leanback Preferences ライブラリには、プラットフォームと整合する設定画面と設定画面が用意されていますが、アプリに合わせてテーマを設定できます。
  • Leanback ページング ライブラリは、ObjectAdapters の AndroidX ページング モデルをサポートしています。これは、Leanback テンプレートでよく使用されます。
  • Leanback Tabs ライブラリは、Android TV でのタブ形式のナビゲーションをサポートしています。

Leanback ページング ライブラリ

Leanback のページングは AndroidX の Paging 3 ライブラリと同じように動作します。これにより、RecyclerView.Adapter にページングを簡単に追加できます。Leanback では、公開されるアダプターは通常、代わりに ObjectAdapter であるため、Leanback ページング ライブラリは ObjectAdapter にページングのサポートを追加します。

まず、プロジェクトにライブラリを追加します。

implementation "androidx.leanback:leanback-paging:$version"

その後、androidx.paging.PagingDataAdapter の代わりに androidx.leanback.paging.PagingDataAdapter を使用して、Paging 3 のドキュメントに従います。唯一の違いは、Presenter または PresenterSelector を渡せるようになったことです。これは、ListRow など、通常 ObjectAdapter を使用するすべての場所で機能します。

Kotlin

val adapter: PagingDataAdapter<MyItem> = PagingDataAdapter(myPresenter,
   object : DiffUtil.ItemCallback<MyItem>() {
       override fun areItemsTheSame(
           oldItem: MyItem,
           newItem: MyItem
       ): Boolean {
           return oldItem.id === newItem.id
       }

       override fun areContentsTheSame(
           oldItem: MyItem,
           newItem: MyItem
       ): Boolean {
           return oldItem == newItem
       }
   })

val header = HeaderItem(headerTitle)
val row = ListRow(header, adapter)

Java

PagingDataAdapter<MyItem> adapter = new PagingDataAdapter(myPresenter, new DiffUtil.ItemCallback<MyItem>() {
    @Override
    public boolean areItemsTheSame(@NonNull MyItem oldItem, @NonNull MyItem newItem) {
        return oldItem.getId().equals(newItem.getId());
    }

    @Override
    public boolean areContentsTheSame(@NonNull MyItem oldItem, @NonNull MyItem newItem) {
        return oldItem.equals(newItem);
    }
});

HeaderItem header = new HeaderItem(headerTitle);
Row row = new ListRow(header, adapter);

Leanback Tabs ライブラリ

Leanback テンプレートは、ブラウズ エクスペリエンスにサイド ナビゲーションを提供します。これは多くのアプリで適切に機能します。タブ ナビゲーション(通常はアプリの上部を横方向に表示)が必要な場合は、代わりに Leanback タブを使用できます。

プロジェクトにライブラリを追加します。

implementation "androidx.leanback:leanback-tab:$version"

次に、既存の ViewPager ガイドに沿って、LeanbackTabLayoutLeanbackViewPager を使用してタブを実装します。LeanbackViewPager は、ViewPager2 ではなく ViewPager に基づいています。

簡単な例を以下に示します。

Kotlin

val leanbackTabLayout = findViewById<LeanbackTabLayout>(R.id.tab_layout)
val leanbackViewPager = findViewById<LeanbackViewPager>(R.id.view_pager)

leanbackViewPager.setAdapter(adapter)
leanbackTabLayout.setupWithViewPager(leanbackViewPager)

Java

LeanbackTabLayout leanbackTabLayout = findViewById(R.id.tab_layout);
LeanbackViewPager leanbackViewPager = findViewById(R.id.view_pager);

leanbackViewPager.setAdapter(adapter);
leanbackTabLayout.setupWithViewPager(leanbackViewPager);

制限事項

Leanback Tabs ライブラリには次の制限があります。

サポートされているテーマ

Theme.AppCompat から派生したテーマのみがサポートされています。TabLayout にはテーマ適用制約が含まれており、Theme.AppCompat の子孫以外のテーマが使用されなくなります。Leanback のブリッジテーマを使用することもできます。

タブから最上部に移動するフォーカス

レイアウトの高さが画面の高さよりも高く、D-pad の上ボタンを押すと、コントロールがタブに戻り、フラグメント内にとどまって上のアイテムに移動することはありません(動画を参照)。この問題に対処するには、フラグメント内のコンテンツでフォーカス検索をオーバーライドする必要があります。たとえば、この問題に対処するには RowsSupportFragment を使用します。BrowseSupportFragment はオーバーライドされたフォーカス検索メソッドがあり、フォーカスがタブに戻れなくなるため、タブ内では使用できません。