MultipurposeMachine 双 DPI(160 / 240 dpi)兼容性完整整改方案

1. 结论与目标

本项目现有 UI 以 YoungFeel YF_029E 的 1080 x 1920160 dpi 为唯一视觉基准开发;在该设备上 1dp = 1px。K203 同为 1080 x 1920,但 density 为 240 dpi,即 1dp = 1.5px。因此,固定 dp 尺寸在 K203 上会放大 1.5 倍:例如 1000dp 宽的弹窗会变为 1500px,超过 1080px 屏幕。

整改目标不是重新设计两套 UI,也不修改 YoungFeel 的既有观感;目标是让 K203 呈现与 YoungFeel 一致的像素级主视觉,并保证未来维护者不会再次把固定像素设计误写成未分档的 dp

2. 设备基线与适配原则

项目YoungFeel YF_029EK203
物理分辨率1080 x 1920 px1080 x 1920 px
density160 dpi / 1.0240 dpi / 1.5
可用逻辑宽度1080dp720dp
现有视觉基准
  1. res/values/ 与现有 UI 继续代表 YoungFeel 160 dpi 基准,不做批量回归改动。
  2. 仅对需要保持同一像素尺寸的组件新增 res/values-hdpi/ 覆盖资源;K203 数值为 YoungFeel 基准值的 2/3
  3. 文字继续用 sp;最小点击区、通用圆角、常规 1dp 分割线保持标准密度语义。
  4. 页面主体优先使用 match_parent、权重、约束或可用空间计算;固定设计元素使用分档尺寸资源。
  5. 不修改系统 density,也不全局将 dp 转 px。

3. 统一资源与代码约定

3.1 新增资源文件

例如:dialog_width_large 为 1000dp / 666.67dp,dialog_width_face 为 900dp / 600dp,dialog_action_height 为 120dp / 80dp。菜品页已新增 food_meal_segment_text_size(20sp / 13.33sp)、food_category_tab_width(132dp / 88dp)、food_category_tab_height(48dp / 32dp)和 food_category_tab_text_size(20sp / 13.33sp)。需要像素一致的尺寸一律经 @dimen/... 引用,不再在 XML 新增裸写的大型固定尺寸。

3.2 动态创建 View、自绘控件与图片

4. 全量审计范围与判定口径

审计清单逐项记录文件、位置、当前值、用途、分类、YoungFeel 实际 px、K203 目标值、实施状态和截图编号。

分类判定处理方式
A. 固定像素设计尺寸弹窗、标题栏、输入框、按钮、视觉卡片资源化,hdpi 取 2/3
B. 自适应结构尺寸页面主体、列表可用区、图表绘制区约束、权重、比例或可用空间计算
C. 标准语义尺寸常规间距、圆角、最小点击区、分割线保持 dp
D. 文本尺寸textSize、setTextSize、Canvas 字号保持 sp,修复错误 px/dp
E. 位图资源背景、装饰图、图标按原始像素需求与容器尺寸分别处理

审计覆盖全部 XML、drawable、Java 动态布局、PopupWindow/Dialog/Toast/Loading、自定义 View 测量绘制与全部位图资源。

5. 分批整改任务

第一批:资源基座与核心全屏弹窗

覆盖密码、单输入、提示、配对、人脸激活、版本、单选等弹窗及其 Java 窗口类。将 500dp、900dp、1000dp 和关联标题、输入区、按钮、边距资源化;保持全屏遮罩和实际 px 窗口逻辑。验收:双机卡片实际 px 一致、K203 无溢出、键盘交互正常。

第二批:人脸识别、采集与相机预览

覆盖 face_recognition_pop_layout.xmltake_photo_pop_layout.xmlset_senior_fragment_layout.xml 及 FaceRecognitionPop、FaceStudyPop、SetSeniorFragment、预览测量链路。外框尺寸资源化;预览按明确比例测量,并同时核验请求尺寸、容器、方向和 AutoTexturePreviewView 测量。验收:弹窗一致、预览无拉伸、摄像头配置复用无回归。

第三批:设置、人员与部门选择页面

覆盖设置、人员、部门选择、人员列表及关联 Adapter/Dialog。固定行高和卡片资源化;将部门弹窗 800dp 固定列表改为可用窗口高度约束。验收:列表完整可滚动,底部操作区不遮挡。

第四批:首页、菜品、打印与营养页面

覆盖首页、菜品列表、打印、营养报表及动态 LayoutParams。页面主体改为可用空间结构;卡片和图表固定视觉值资源化;动态图表按“容器比例”和“适配资源”拆分。验收:页面无裁切,图表文字可读且不重叠。

FoodListActivity 餐次与菜品分类专项(已实施:2026-07-20)

本专项继续遵循“默认资源保持 YoungFeel 视觉基准,K203 固定视觉尺寸取 2/3”的规则,不增加设备型号判断。

控件YoungFeel 160 dpiK203 240 dpi目标物理像素(fontScale=1.0)实现位置
餐次控件外框380dp × 48dp253.33dp × 32dp约 380px × 48pxadaptive_size_380 / adaptive_size_48
餐次文字20sp13.33sp约 20pxfood_meal_segment_text_size
分类按钮132dp × 48dp88dp × 32dp132px × 48pxfood_category_tab_width / food_category_tab_height
分类文字20sp13.33sp约 20pxfood_category_tab_text_size

分类间距继续使用 adaptive_size_16,圆角继续使用 adaptive_size_8;两者已有 K203 覆盖。此次不改变餐次选择、分类过滤或菜品加载逻辑。JDK 8 下执行 :app:testDebugUnitTest:app:assembleDebug 均构建成功;双机截图对照仍为最终视觉验收项。

第五批:自定义 View、系统提示与资源收口

覆盖 CustomTwoOptionView、NetWorkStatusView、DietaryPagodaView、FoodCategoryBarChartView、SegmentedMealTabView、SplitEditText、ToastUtils、ProgressDialogHelper 及其他命中单位转换的类。清理不必要的 COMPLEX_UNIT_PX,收口图表、提示与图片资源。验收:提示不超屏,自绘图形不越界,无新增裸写大型固定 dp。

NetWorkStatusView 顶部栏专项

范围包括 BaseActivity.java 的顶部栏容器与内容区内边距,以及 NetWorkStatusView.java 动态创建的返回按钮、箭头、Logo、网络图标、时间和日期区域。

验收:YoungFeel 保持现有 160 dpi 视觉;K203 上顶部栏、返回按钮、图标及固定间距与 YoungFeel 的实际 px 一致(取整误差不超过 1px),文字不截断,返回按钮可点击。

6. 实施约束与非目标

7. 验证矩阵

JAVA_HOME=$(/usr/libexec/java_home -v 1.8) sh ./gradlew :app:assembleDebug

每批同时在 YoungFeel 和 K203 检查启动首页、核心弹窗、人脸预览、部门人员、菜品打印、营养报表。K203 固定设计元素相对 YoungFeel 的实际像素误差不超过 1px(取整误差),且无文字裁切、横向溢出、不可点击或预览拉伸。

8. 风险与控制

风险控制措施
全量缩小 dp 使文字和点击区过小先审计分类,仅 A 类走 hdpi 覆盖
XML 修复后 Java 动态 View 仍放大同步扫描 LayoutParams、dp()、setTextSize()
相机预览变形同时验证尺寸、方向与预览测量链路
位图处理造成模糊仅确认的固定像素背景使用 nodpi,逐图验证
YoungFeel 回归默认 values 不改视觉值,每批先回归 YoungFeel

9. 完成定义

  1. 审计清单覆盖所有 XML、动态布局、自定义 View、窗口与位图资源。
  2. 所有固定像素设计尺寸已资源化并有 hdpi 覆盖。
  3. YoungFeel 保持既有观感;K203 无溢出、裁切、拉伸或不可读问题。
  4. 五批整改均完成构建、双机验证与截图留档。
  5. 每次实现变更均记录到外部 CHANGELOG。

10. 当前状态

本文件既作为已确认方案,也持续记录实际实施状态。双 DPI 资源基座已经建立,多个整改批次正在按页面推进。截至 2026-07-20,FoodListActivity 的页面固定尺寸、餐次控件外框、餐次自绘文字以及菜品分类按钮宽高和文字均已接入 YoungFeel / K203 双档资源;全量单元测试和 debug APK 打包通过,尚待两类设备实机截图对照确认。