ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

让遥控器不再打滑:TV 直播应用的焦点与布局 4 个关键决策

让遥控器不再打滑:TV 直播应用的焦点与布局 4 个关键决策 让遥控器不再打滑TV 直播应用的焦点与布局 4 个关键决策【免费下载链接】my-tv我的电视 电视直播软件安装即可使用项目地址: https://gitcode.com/GitHub_Trending/my/my-tv遥控器按了半天焦点还在原地打转换台却把频道列表翻到了底TV 直播应用 my-tv 用「全屏播放 悬浮层」的布局结构和启动即定焦点的写法把这个问题处理得很克制。照着它的思路改你的项目换台、看节目单、进设置都能压到 3 次按键以内焦点不再「失踪」。掌握 3 个让屏幕在 3 米外可读的布局决策单容器骨架、40sp 大号频道号、悬浮层定位排查「焦点卡死」问题只需 2 步确认启动时的焦点起点再检查按键事件的分发表复盘 4 次真实迭代v1.7.2 → v2.0.0看懂频道列表怎么从手机移植版变成 TV 原生布局记住 2 个避坑点别把手机的列表布局直接搬上电视Fragment 切换后不调requestFocus方向键会「失聪」定骨架TV 直播应用主界面为什么只要 1 个 FrameLayout这一章解决的是「主界面用什么容器」的问题——答案可能简单到让你意外。my-tv 的主界面文件 app/src/main/res/layout/activity_main.xml 全文只有一个 FrameLayout它的作用就是一个占满全屏的容器频道号、节目信息、设置菜单这些 UI 都以悬浮层的形式盖在视频之上FrameLayout xmlns:androidhttp://schemas.android.com/apk/res/android xmlns:toolshttp://schemas.android.com/tools android:idid/main_browse_fragment android:layout_widthmatch_parent android:layout_heightmatch_parent tools:context.MainActivity tools:deviceIdstv /注意最后的tools:deviceIdstv——它声明这个布局是面向 TV 设备设计的开发阶段就能按大屏预览。这个结构背后的思路电视上的主场景是「视频铺满全屏」所有交互元素都是临时浮上去的。这和手机 App「内容列表为主、全屏只是其中一页」的组织方式正好相反。⚠️避坑如果你的项目是从手机 App 移植过来的先检查根布局是不是 RecyclerView 套 NestedScrollView 那套——用户在 3 米外不会逐行浏览你的列表他们要的是画面 少量悬浮入口。骨架定了下一个问题立刻出现全屏容器里焦点一开始该在哪找回焦点起点启动和换页时把 requestFocus 写对焦点「打滑」的常见根因是界面上没人对焦点负责。my-tv 在 app/src/main/java/com/lizongying/mytv/MainActivity.kt应用入口负责按键分发和 Fragment 管理里主 Fragment 加载完成后直接显式要焦点// MainActivity.kt 启动阶段把焦点起点钉在主 Fragment 上 mainFragment.view?.requestFocus()你可以把requestFocus()理解成给遥控器指了个「起点」用户拿起遥控器按第一下方向键时系统才知道该往哪个方向找下一个目标。不做这一步焦点可能落在一个不可聚焦的容器里之后按任何方向键都无反应——这就是用户嘴里「遥控器坏了」的真相。实操技巧TV 项目里每次 Fragment 切换、每次重建视图都值得问一遍「焦点现在在哪」。这条排查路径能帮你 2 分钟内定位绝大多数「方向键失灵」工单。焦点有了起点接下来要让每个方向都「有路可走」——这就轮到按键路由出场了。给遥控器每个键分配固定职责按键事件这样分发TV 遥控器没有鼠标、没有右击全部操作都压在一把键帽上所以每个键的含义必须稳定、可预期。my-tv 的做法是在 MainActivity.kt 里用一张when分发表把不同来源的按键归并成少数几个动作。下面是这张分发表的骨架各分支具体动作省略when (keyCode) { KeyEvent.KEYCODE_BACK - { /* 退出 / 返回 */ } KeyEvent.KEYCODE_MENU - { /* 呼出菜单 */ } KeyEvent.KEYCODE_DPAD_UP - { /* 换台 */ } KeyEvent.KEYCODE_CHANNEL_UP - { /* 换台 */ } KeyEvent.KEYCODE_DPAD_DOWN - { /* 换台 */ } KeyEvent.KEYCODE_CHANNEL_DOWN - { /* 换台 */ } KeyEvent.KEYCODE_DPAD_LEFT - { /* 打开频道列表 */ } KeyEvent.KEYCODE_DPAD_RIGHT - { /* 打开设置菜单 */ } }这段在干什么把「方向键上滑/下滑」和「专用换台键 CHANNEL_UP/DOWN」归并到同一个换台动作保证不同品牌遥控器有的只有方向键有的带频道键按出来的效果完全一致。上下的语义可以对照 my-tv 仓库里这张按键示意上/下负责换频道中间确认键用于呼出菜单左右键分别打开频道列表和设置。⚠️避坑改键位语义要慎重。my-tv 在 v1.7.8 把「左键开频道列表、右键开设置」这套语义定下来后就没再动过——键位是用户用肌肉记忆学会的改一次就得教育一遍。按键路由解决了「去哪」最后一个视觉问题是到了的地方3 米外看得清吗按 3 米外能看清的标准定字号与间距TV 界面的字号标准不是「手机上舒服」而是「沙发上不眯眼」。频道号悬浮层 app/src/main/res/layout/channel.xml右上角的换台提示就给出了项目里最直白的一组参数TextView android:idid/channel_content android:layout_widthwrap_content android:layout_heightwrap_content android:layout_gravityend android:textColor#FFEEEEEE android:textStylebold android:textSize40sp /40sp 加粗、浅灰白文字配合深色播放背景就是「远距离可见性」的全部秘密字号给够、字重加粗、对比度拉满。间距上项目遵循 8dp 的倍数网格channel.xml 里悬浮层距顶部 20dp、距右缘 170dp都是刻意留出的「安全区」让频道号既不挡画面主体又不会贴边。颜色方面项目把各状态色值集中放在 app/src/main/res/values/colors.xml全局颜色值定义方便统一调整焦点高亮与正文的对比度。实操技巧写完布局后别只看手机模拟器用 TV 预览或把模拟器分辨率调成 1080p 放到 1 米外看验收一遍字号不够的问题一眼就能暴露。视觉和按键都就位了但真实项目很少一步到位——频道列表这块就反复返工了 4 个版本。频道列表的 4 次迭代从手机移植版到 TV 原生布局频道列表是 my-tv 里交互密度最高的组件它的演进过程完整地记录在 HISTORY.md项目更新日志值得当成案例拆解。最初的方案是把手机上的列表样式直接搬上来。很快暴露出两类问题一是样式切换后需要重启才生效二是列表展开后「按哪关不掉」说不清。于是有了这几轮修改均以更新日志原文为准v1.7.2频道列表支持网格和行两种样式切换——承认了「一屏放 8 个台」和「一屏看 3 个台」是两种需求v1.7.8左键开列表、右键开设置同时定了「点空白处收起列表」把「怎么关掉」写进了规则v2.0.0修复网格样式下点空白处不退出、样式切换不生效两个回归问题——双样式带来的边界情况终于补齐对照 app/src/main/res/layout/全部页面布局文件可以看到最终形态就是「一个全屏容器 几个定位明确的悬浮层」列表、节目信息、时间、设置各自独立成页互不嵌套。复盘启示这四版迭代里没有任何「大重构」全部是对交互细节的修补——样式开关要即时生效、每个入口要有明确的出口。TV 项目的大部分返工都发生在这类「小事」上。收束三条能带走的判断标准钉住焦点起点启动和每次页面切换后确认requestFocus()已经执行给每个键固定一个职责换台键、方向键、左右键各管一件事并且长期不改按 3 米验收字号和间距40sp 频道号、8dp 间距网格、深浅对比拉满想深挖的话这三个位置值得先看app/src/main/java/com/lizongying/mytv/MainActivity.kt按键分发和焦点起点的核心实现app/src/main/res/layout/channel.xml远距离可见性的一组参考参数HISTORY.md频道列表 4 次迭代的完整时间线如果这篇帮到了你可以去 star 一下项目或者git clone https://gitcode.com/GitHub_Trending/my/my-tv把代码拉下来跑起来看。下期我们聊一个更硬核的话题TV 应用里播放失败怎么重试才能不黑屏——更新日志里「修复不能播放」出现过十几次背后的重试逻辑值得单独写一篇。【免费下载链接】my-tv我的电视 电视直播软件安装即可使用项目地址: https://gitcode.com/GitHub_Trending/my/my-tv创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表