3、TV应用基础结构:Leanback库介绍、Activity与Fragment在TV中的使用
好,咱们今天聊聊TV应用的基础骨架。说白了,就是搞清楚Leanback库是干嘛的,以及Activity和Fragment在电视上该怎么用。
我刚开始做TV开发时,也踩过不少坑。手机上的那套写法,搬到电视上,很多地方行不通。为什么?因为交互方式完全不同。手机靠触摸,电视靠遥控器。你想想看,一个没有触摸屏的设备,你总不能用手指去戳屏幕吧?
所以,Google专门搞了个Leanback库。它就是为电视而生的。
3.1 Leanback库:TV开发的基石
Leanback库,说白了就是一套专门给电视用的UI组件和工具集。它帮你处理了焦点移动、按键导航、大屏布局这些头疼的问题。
我个人习惯,每次新建TV项目,第一件事就是引入Leanback依赖。别嫌麻烦,它真的能省很多事。
核心依赖:
implementation 'androidx.leanback:leanback:1.0.0'
Leanback库提供了几个关键的东西:
- BrowseFragment:浏览页面的核心,帮你搭建分类和内容列表
- DetailsFragment:详情页面的基础框架
- PlaybackFragment:播放器相关的UI组件
- 各种Presenter:负责把数据渲染成界面上的卡片
我记得有一次,团队里新来的同事想自己写焦点管理,折腾了两天,各种bug。后来我让他直接用Leanback的BrowseFragment,半天就搞定了。嗯,这里要注意,不要重复造轮子。
3.2 Activity在TV中的特殊之处
TV上的Activity,和手机上的Activity,本质上是一样的。但有几个关键点,你得注意。
第一,主题必须用NoActionBar。
电视上不需要ActionBar,那玩意儿占地方,而且遥控器操作起来也不方便。
<activity
android:name=".MainActivity"
android:theme="@style/Theme.Leanback">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
</activity>
看到那个 category.LEANBACK_LAUNCHER 了吗?这是TV应用特有的。没有它,你的应用在电视上可能无法被识别为可启动的应用。
第二,屏幕方向固定为横屏。
电视永远是横屏的。别想着搞竖屏,那在电视上就是个灾难。
android:screenOrientation="landscape"
我曾经见过一个应用,没设置横屏,结果在电视上显示得歪歪扭扭。用户遥控器按了半天,焦点都不知道跑哪去了。
3.3 Fragment:TV界面的主力军
在TV开发中,Fragment的使用频率远高于Activity。为什么?因为电视屏幕大,内容多,用Fragment做模块化拆分,管理起来更清晰。
Leanback库里的核心Fragment,我列一下:
| Fragment | 用途 | 我常用的场景 |
|---|---|---|
| BrowseFragment | 主界面浏览,分类+内容列表 | 首页、频道列表 |
| DetailsFragment | 展示某个内容的详细信息 | 电影详情、商品详情 |
| PlaybackFragment | 视频播放控制界面 | 播放器UI |
| SearchFragment | 搜索功能 | 全局搜索 |
拿BrowseFragment举个例子。你想想看,电视上的首页,左边是分类列表,右边是内容卡片。这个布局,用BrowseFragment实现起来非常方便。
public class MainFragment extends BrowseFragment {
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// 设置标题
setTitle("我的TV应用");
// 设置UI风格
setHeadersState(HEADERS_ENABLED);
setBrandColor(getResources().getColor(R.color.primary));
// 加载数据
loadRows();
}
private void loadRows() {
// 这里用ArrayObjectAdapter添加数据行
ArrayObjectAdapter rowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
// ... 添加具体数据
setAdapter(rowsAdapter);
}
}
你看,代码量并不多。Leanback帮你处理了焦点移动、按键事件、布局适配。你只需要关心数据怎么来,卡片长什么样。
小技巧: 在BrowseFragment中,如果你想让分类标题一直显示,可以调用 setHeadersState(HEADERS_ENABLED)。如果想让标题自动隐藏,用 HEADERS_DISABLED。我个人习惯在内容较多的页面让标题常驻,方便用户快速切换分类。
3.4 焦点管理:TV交互的灵魂
电视上没有触摸,全靠遥控器上的方向键和确认键。所以,焦点管理是TV开发的重中之重。
Leanback库的组件,默认就支持焦点移动。但如果你用了自定义View,就得手动处理了。
我曾经在一个项目中,用了自定义的卡片布局,结果焦点移动不按套路走。用户按右键,焦点跳到下面去了。排查了半天,发现是布局里某个View的 android:nextFocusRight 属性没设置对。
避坑指南: 自定义View时,一定要显式指定焦点移动方向。用 android:nextFocusDown、android:nextFocusUp、android:nextFocusLeft、android:nextFocusRight 这四个属性。别指望系统能自动猜对你的意图。
<Button
android:id="@+id/btn_play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="播放"
android:nextFocusRight="@id/btn_add_favorite"
android:nextFocusLeft="@id/btn_back" />
另外,焦点选中后的视觉效果也很重要。Leanback提供了 FocusHighlightHandler,你可以自定义焦点放大、颜色变化等效果。
3.5 知识体系总览
为了让你更直观地理解TV应用的基础结构,我画了一张图。它把Leanback库、Activity、Fragment以及焦点管理的关系串起来了。
这张图把整个结构理清楚了。从上到下,Activity承载Fragment,Fragment依赖Leanback库,Leanback库帮你搞定焦点和导航。你只要按这个路子走,基本不会出大问题。
3.6 实战中的一些建议
最后,分享几个我在实战中总结的点:
- 别在TV上用DialogFragment:电视上的弹窗体验很差,尽量用内嵌的Fragment或者Overlay代替。
- Fragment的切换用FragmentTransaction:记得加上
addToBackStack(null),方便用户按返回键回退。 - 数据加载用异步:电视的硬件性能参差不齐,别在主线程做耗时操作。我用过一些低端盒子,稍微卡一下,用户就以为死机了。
核心总结: TV应用的基础结构,就是Activity + Leanback Fragment + 焦点管理。把这三块搞明白,你的TV应用就站稳了脚跟。
好了,这一章的内容就到这里。记住,电视开发没那么神秘,关键是理解它的交互逻辑。Leanback库已经帮你铺好了路,你只需要沿着它走就行。
公众号:蓝海资料掘金营,微信deep3321