AndroidX TV 库

大多数 AndroidX 库都可以与 Android TV 配合使用。您可以使用 ViewModel架构组件来管理生命周期感知型界面数据,使用 Room 轻松使用本地 SQLite 数据库,就像使用移动设备一样;不过,也有一些 TV 专用库支持 Android TV 独有的功能。这些库包括:

  • Leanback 库提供界面模板,可简化 Android TV 应用的创建过程。
  • Leanback 偏好设置库提供与平台一致的偏好设置和设置屏幕,但可以设置与应用相匹配的主题。
  • Leanback Paging 库支持 ObjectAdapters 的 AndroidX 分页模型,该模型通常与 Leanback 模板一起使用。
  • Leanback Tabs 库支持 Android TV 上的标签页式导航。

Leanback Paging 库

Leanback 分页的工作方式与 AndroidX Paging 3 库相同,后者简化了向 RecyclerView.Adapter 添加分页的流程。对于 Leanback,公开的适配器通常是 ObjectAdapter,因此 Leanback Paging 库为 ObjectAdapter 添加了分页支持。

首先,将该库添加到您的项目中:

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

然后,您可以按照 Paging 3 文档中的说明进行操作,使用 androidx.leanback.paging.PagingDataAdapter(而不是 androidx.paging.PagingDataAdapter)。唯一的区别是您现在可以传入 PresenterPresenterSelector。这适用于您通常使用 ObjectAdapter 的任何位置,例如在 ListRow 中:

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 标签页库

Leanback 模板在浏览体验中提供侧边导航,这非常适合许多应用。如果您需要标签页导航(通常在应用顶部水平显示),可以改用 Leanback 标签页。

将该库添加到您的项目中:

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

然后,按照现有的 ViewPager 指南使用 LeanbackTabLayoutLeanbackViewPager 实现标签页。请注意,LeanbackViewPager 基于 ViewPager,而不是 ViewPager2

一个简单的示例如下所示:

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 的桥接主题背景。

将焦点从标签页移至顶部

当布局高度大于屏幕高度并且您按方向键向上按钮时,控件会移回标签页,而不是停留在 fragment 内并导航到其上方的项(请观看视频)。为了解决此问题,fragment 内部的内容必须替换焦点搜索。例如,请使用 RowsSupportFragment 处理此问题;不能在标签页内使用 BrowseSupportFragment,因为它具有已替换的焦点搜索方法,该方法会阻止焦点移回标签页。