news 2026/9/4 1:05:07

遥控器焦点乱跑?my-tv 的 5 个布局决策

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
遥控器焦点乱跑?my-tv 的 5 个布局决策

遥控器焦点乱跑?my-tv 的 5 个布局决策

【免费下载链接】my-tv我的电视 电视直播软件,安装即可使用项目地址: https://gitcode.com/GitHub_Trending/my/my-tv

用户按了三次方向键,焦点从频道列表跳到了右上角的"帮助"按钮上。TV 应用 UI 设计的核心就是这件事:屏幕大、遥控器键少,焦点自己走,必然走到用户没预期的地方。my-tv 是个装完就能看的电视直播应用,它的第一步是把焦点的活动范围收窄。

主界面只是一个空壳

activity_main.xml 里只有一个根 FrameLayout,没有子节点,还标了tools:deviceIds="tv"

<FrameLayout android:id="@+id/main_browse_fragment" tools:deviceIds="tv" />

真正的界面是运行时由 Leanback 的 BrowseSupportFragment 注进来的,布局文件只声明"这页只给电视用"。Leanback 的 BrowseFragment 配置其实就一行,MainFragment.kt 的 onCreate 第一句:

headersState = HEADERS_DISABLED // 不显示头部和搜索栏

数据来自 TVList.kt 里的一个 map,央视、地方、港澳台、国际 4 组,每组一行 ListRow,卡片上放频道 logo 加正在播出的节目名。好处是焦点只能在 4 行卡片之间动,按不到屏幕边缘,用户怎么按都不会迷路。

遥控器就几个键,导航必须可预测

能参与导航的按键其实就 5 个:上下切频道、中间确认、返回、帮助。所以焦点路径必须可预测。CardPresenter.kt 里的写法最直白:

cardView.isFocusable = true cardView.isFocusableInTouchMode = true

卡片 300x101 像素,白底,logo 居中。高亮色#0096a6定义在 colors.xml 里,但翻代码会发现对应的 setOnFocusChangeListener 是被注释掉的——本来想聚焦时把信息区背景换成高亮色,后来放弃了,高亮完全交给 Leanback 默认的缩放和边框。我的体感是这更稳:框架的聚焦动画统一,自己画反而容易和各系统版本打架。

导航路径则完全靠 ListRowPresenter 的默认算法:这 5 个 Android TV 布局文件里没有一处 nextFocusRight。行式结构下这够用——左右在行内走,上下切行,路径由行数决定。换成二维网格就不能指望默认值了,得手写路径。

网格改行式:频道列表样式的一次退让

频道列表不是一直长这样的。翻 HISTORY.md,v1.6.2 加了新的列表样式,v1.7.2 支持网格/行式切换,但注了条"软件重启后生效"。到 v2.0.0 一次修了两个 bug:"网格样式时点击空白处不退出"和"频道列表样式切换可能不生效"。

这是典型的取舍。网格一屏放得下更多频道,好看;但焦点变二维,遥控器没有滚动指示器,用户不知道右边还有没有频道,按着按着就丢了。行式焦点简单,配合菜单 3 秒自动关闭(v1.3.4 引入),把"停留在列表里"的时间也限制了。项目最后把网格留在设置里当选项,默认体验走行式。样式不做热切换、要重启生效,是妥协:比起切换瞬间维护两份焦点状态,重启更不容易出 v2.0.0 那种"切换不生效"的 bug。

间距用 dp 算,不用"合适"

定了行式,下一个问题是三米外看不看得清。频道号层 channel.xml 是个 90dp x 60dp 的盒子,40sp 粗体白字,marginEnd 170dp钉在右上;时钟层 32sp,marginEnd 50dp。两层同在右上角但不打架,就是靠这两个错开的偏移量。节目信息条 320dp x 80dp,距底边 20dp,标题 22sp 用#FFEEEEEE,节目名 16sp 用#B3EEEEEE——两行字靠透明度差 70% 分主次,这在电视上比换颜色可靠。设置弹层只有 300dp 宽,不铺满屏,4 个 Switch 竖排,遥控器按一下挪一格,按不到边界。

播放器页故意没有系统控制条

播放时所有浮层收起,剩下最"空"的文件 player.xml,全文不到 30 行:SurfaceView 和 media3 的 PlayerView 叠在黑色背景里,两个都写了:

<androidx.media3.ui.PlayerView app:use_controller="false" />

系统控制条关掉,控制层自己画——频道号、时钟、信息条全叠在视频上。原因不复杂:系统控制条的焦点体系不知道你的应用状态,用户播放中误按方向键,焦点会飞出视频区钻进控制条。关掉之后,播放器页焦点只剩频道列表浮层和空白处,方向键按错了也不出界。

打开 channel.xml,把 marginEnd 从 170dp 改成 120dp,看看频道号贴到右边之后还留没留得下时钟。

【免费下载链接】my-tv我的电视 电视直播软件,安装即可使用项目地址: https://gitcode.com/GitHub_Trending/my/my-tv

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/4 12:34:42

Ryujinx 快速上手:全平台 Switch 模拟器从零到满帧

Ryujinx 快速上手&#xff1a;全平台 Switch 模拟器从零到满帧 【免费下载链接】Ryujinx 用 C# 编写的实验性 Nintendo Switch 模拟器 项目地址: https://gitcode.com/GitHub_Trending/ry/Ryujinx 手柄的震动反馈里&#xff0c;你正策马穿过旷野&#xff0c;镜头甩向雪山…

作者头像 李华
网站建设 2026/9/3 20:23:28

DQ08 PRO和HK1 RBOX K8-瑞芯微RK3528芯片-安卓13.0-刷机固件包

DQ08 PRO和HK1 RBOX K8-瑞芯微RK3528芯片-安卓13.0-刷机固件包DQ08 Pro机顶盒HK1 RBOX K8 机顶盒刷机步骤: 1.正常线刷一次压缩包里的原厂包&#xff0c;不会的自己搜一下线刷教程就行了&#xff1b; 2.在刷一次Spuer分区即可&#xff0c;必须用压缩包里的2.84版刷&#xff1b;…

作者头像 李华
网站建设 2026/9/4 8:29:38

模拟太阳系源码解析:天体运动与Unity工程实践

简介&#xff1a;这是一份关于太阳系动画模拟的源代码与素材包&#xff0c;面向想要学习图形编程、物理模拟或天体运动可视化的初中级开发者&#xff0c;也可作为编程教学中的演示案例。包内共23个文件&#xff0c;包括20张PNG格式的星球与背景图、1张JPG图片、1个HTML页面以及…

作者头像 李华
网站建设 2026/9/3 17:23:43

基于Matlab/Simulink的光伏MPPT仿真:从电池建模到算法实现

简介&#xff1a;本资源是一套基于Matlab平台实现光伏电池最大功率点跟踪&#xff08;MPPT&#xff09;算法的仿真源码包&#xff0c;面向电子信息工程、自动化、新能源科学与工程及数学相关专业的本科生&#xff0c;适用于课程设计、期末大作业或毕业设计阶段的实践参考。资源…

作者头像 李华
网站建设 2026/9/4 15:29:06

C++ Qt实战:打造Windows实时系统监控工具

这次我们来看一个很适合作为“系统编程第一个工程项目”的 Qt 实战项目&#xff1a;Windows 实时系统监控工具。项目本身不复杂&#xff0c;但把 C 系统编程和 Qt 桌面开发最常见的内容都串起来了&#xff1a;Windows 系统 API 调用、定时采集、多线程、图表绘制、进程列表、界…

作者头像 李华
网站建设 2026/9/4 16:31:15

MediaPipe 完整指南:5 分钟跑通人脸检测与手部追踪

MediaPipe 完整指南&#xff1a;5 分钟跑通人脸检测与手部追踪 【免费下载链接】mediapipe Cross-platform, customizable ML solutions for live and streaming media. 项目地址: https://gitcode.com/GitHub_Trending/med/mediapipe 你想在应用里加人脸识别或手势控制…

作者头像 李华