用户第二轮功能反馈来了 11 项:BACK 作用域、页面白闪、字体车载放大、DLNA 错显、列表跳动、双视图、ID3 封面、播放列表清空……一天到几天修一轮,这篇记当天 UI 批次里三个最有味道的:180° 旋转、双视图布局、行高治理。

先说工作方法:这轮清单按"任务 + 根因 + 验证命令 + 状态"四要素登记成条目,完工一条核销一条——防漏项比修得快更重要,前一轮有过"计划清空了但旧条目没逐条核实"的教训。

一、180° 旋转:屏转了,输入坐标系要跟着转

需求:整机安装方向倒置,界面要转 180°。

实现:合成"机型安装角度 + 用户 180° 设置",一次调用 lv_display_set_rotation 完成真旋转——不是把每个页面重画一遍,旋转是显示层的属性,不该散落在业务层。

踩坑:屏转完发现方向键没跟着转——按"上"光标往"下"走。物理屏转了 180°,输入坐标系和输出坐标系必须一起转:Up/Down 互换、Left/Right 互换。输出旋转是显示层的事,输入旋转是输入映射的事,两件事总是成对出现,只做一半的旋转比不旋转更折磨人。

二、双视图:左浏览右队列,宽度用脚投票

需求:播放列表页做双栏——左栏 U 盘浏览,右栏当前播放队列(只读)。

第一版按直觉左右均分。上机一看反了:队列每行只有"序号 + 曲名",浏览栏每行是"目录/文件 + 状态图标"——信息密度决定栏宽,均分让窄内容的队列占了半屏。第二版左右宽度对调:队列栏收窄、浏览栏加宽,一眼舒服。

顺带一个工程细节:这个面板工程被工具链钉死在 C++14(musl GCC 6.4,无 std::optional/嵌套命名空间简写),新代码写着写着就会滑进 C++17 语法,编译才炸。C++14 改写嵌套命名空间是这一轮的固定动作。

三、行高治理:行高不是样式,是命中测试的边界

两个连环问题:

  1. 歌名裁切:共享媒体字库的默认行高和界面字号不匹配,长歌名被削头去尾——用行高覆写(按字库实际行高覆写渲染参数)解决;
  2. 单行误触滚动:列表行文本高度和字库行高差了几像素,指尖按在行的边缘时落在行间隙上——系统判定为列表整体的纵向拖动,一次点选变成一次滚动。修法听着笨:把列表行文本高度精确设置为字库行高,一像素都不差。从此点按和滚动的边界完全由可见行边界决定。

第二条是这天最好的教训:行高不只是视觉样式,它是触摸命中测试的物理边界。视觉上"差不多齐"的布局,在输入层就是"有时候不是这行"。

尾声

次日接着补了两件相关项:BACK 键在 USB 播放页改为"全屏播放列表/浏览两页、左右键切换"(作用域问题换了种更顺手的解法),以及协议新增代际号与采样率格式两条查询命令对齐下位机。清单制的好处在这轮体现得很直白:11 项里哪项修了、哪项定性到下位机、哪项还在挂账,随时一句话说清。