自适应设计最佳实践
自适应设计部分最佳实践摘要。
自适应设计的推荐最佳实践包括:
设计考量
#拆分 widget
#设计应用时,尽量将大型、复杂的 widget 拆分为更小、更简单的 widget。
重构 widget 可通过共享核心代码降低采用自适应 UI 的复杂度,还有其他好处:
-
On the performance side, having lots of small
constwidgets improves rebuild times over having large, complex widgets. -
Flutter can reuse
constwidget instances, while a larger complex widget has to be set up for every rebuild. -
From a code health perspective, organizing your UI into smaller bite sized pieces helps keep the complexity of each
Widgetdown. A less-complexWidgetis more readable, easier to refactor, and less likely to have surprising behavior. 在性能方面,大量小型
constwidget 比大型复杂 widget 更能缩短重建时间。Flutter 可复用
constwidget 实例,而较大的复杂 widget 每次重建都需重新设置。-
从代码健康角度看,将 UI 组织成更小的片段有助于降低每个
Widget的复杂度。复杂度较低的Widget更易读、更易重构,也更少出现意外行为。
要了解更多,请参阅 General approach 中的自适应设计三步法。
针对各形态优势进行设计
#除屏幕尺寸外,你还应花时间考虑不同形态的独特优势与劣势。多平台应用并非在所有地方提供完全相同功能总是理想选择。考虑是否在某些设备类别上聚焦特定能力,甚至移除某些功能。
例如,移动设备便携且带相机,但不适合精细创意工作。据此,移动 UI 可更侧重内容采集与位置标记,平板或桌面 UI 则侧重组织或编辑该内容。
另一例是利用 Web 极低的分享门槛。若部署 Web 应用,决定支持哪些深度链接,并据此设计导航路由。
要点是思考各平台最擅长什么,以及能否利用独特能力。
先解决触控
#构建出色的触控 UI 往往比传统桌面 UI 更难,部分原因是缺少右键、滚轮或键盘快捷键等输入加速器。
一种应对方式是先聚焦出色的触控导向 UI。你仍可用桌面目标做大部分测试以加快迭代,但请经常切换到移动设备验证体验是否合适。
触控界面打磨好后,可为鼠标用户调整视觉密度,再叠加其他输入。将这些输入视为加速器——让任务更快的替代方式。重要的是考虑用户使用特定输入设备时的预期,并在应用中体现。
实现细节
#不要锁定应用方向。
#自适应应用应在不同尺寸和形状的窗口上表现良好。在手机上锁定竖屏有助于缩小最小可行产品范围,但会增加日后实现自适应的工作量。
例如,手机仅以全屏竖屏渲染应用并非必然。多窗口应用支持日益普遍,折叠屏也有许多适合多应用并排的场景。
若必须锁定竖屏(但最好不要),请使用 Display API 而非 MediaQuery 等方式获取屏幕物理尺寸。
总结如下:
-
Locked screens can be an accessibility issue for some users
-
Android large format tiers require portrait and landscape support at the lowest level.
-
Android devices can override a locked screen
-
Apple guidelines say aim to support both orientations
锁定屏幕可能对部分用户构成无障碍问题
-
Android 大屏分级在最低层级要求支持竖屏与横屏
-
Android 设备可覆盖锁定屏幕
Apple 指南建议尽量支持两种方向
避免基于设备方向的布局
#
避免在 widget 树顶部附近使用 MediaQuery 的 orientation 字段或 OrientationBuilder 在不同应用布局间切换。这与不要通过设备类型判断屏幕尺寸的建议类似。设备方向也未必告诉你应用窗口有多少空间。
请改用 MediaQuery 的 sizeOf 或 LayoutBuilder,如 General approach
页所述。然后使用 Material
推荐的自适应断点等。
不要占满全部横向空间
#在大屏上运行时,用窗口全宽显示方框或文本字段的应用体验不佳。
要了解如何避免,请参阅 Layout with GridView。
避免检查硬件类型
#避免在布局决策时编写代码判断运行设备是「手机」「平板」或其他类型。
应用实际获得的渲染空间未必与设备全屏尺寸挂钩。Flutter 可在多种平台运行,应用可能在 ChromeOS 的可调整窗口、平板多窗口并排,甚至手机画中画中运行。因此设备类型与应用窗口尺寸并无强关联。
请改用 MediaQuery 获取应用当前运行窗口的尺寸。
这不仅对 UI 代码有帮助。要了解抽象设备能力如何帮助业务逻辑,请参阅 2022 Google I/O 演讲 Flutter lessons for federated plugin development。
支持多种输入设备
#应用应支持基本鼠标、触控板和键盘快捷键。最常见用户流程应支持键盘导航以确保无障碍。尤其在大屏设备上,应用应遵循键盘相关的无障碍最佳实践。
Material 库提供的 widget 在触控、鼠标和键盘交互方面有出色的默认行为。
要了解如何为自定义 widget 添加此类支持,请参阅 User input & accessibility。
恢复 List 状态
#
要在设备方向改变时布局不变的列表中保持滚动位置,请使用 PageStorageKey
类。PageStorageKey
在 widget 销毁后将状态持久化,并在重建时恢复。
可在 Wonderous app
中查看示例,它在 SingleChildScrollView widget 中保存列表状态。
若 List widget 在方向改变时改变布局,屏幕旋转时可能需要一些计算(示例)来调整滚动位置。
保存应用状态
#应用应在设备旋转、窗口尺寸变化或折叠/展开时保留或恢复应用状态。默认情况下,应用应维持状态。
若应用在设备配置变更时丢失状态,请确认所用插件和原生扩展是否支持该设备类型(例如大屏)。部分原生扩展在设备姿态变化时可能丢失状态。
有关此类真实案例的更多信息,请参阅 Medium 免费文章 Developing Flutter apps for Large screens 中的 Problem: Folding/unfolding causes state loss。
除非另有说明,本文档之所提及适用于 Flutter 3.44.0 版本。本页面最后更新时间:2026-06-04。查看文档源码 或者 为本页面内容提出建议。