自适应应用的通用方法

那么,你究竟如何将为传统移动设备设计的应用程序变得在各种设备上都美观?需要哪些步骤?

Google 工程师,他们拥有为大型应用程序执行此操作的经验,建议采用以下 3 步方法。

步骤 1:抽象

#

Step 1: Abstract info common to any UI widget

首先,确定您计划使其动态的部件。分析这些部件的构造函数,并抽象出可以共享的数据。

需要适应性的常见部件包括

  • 对话框,包括全屏和模态对话框
  • 导航 UI,包括轨道和底部栏
  • 自定义布局,例如“UI 区域是更高还是更宽?”

例如,在 Dialog 部件中,您可以共享包含对话框内容的信息。

或者,您可能希望在应用程序窗口较小时切换到 NavigationBar,而在应用程序窗口较大时切换到 NavigationRail。这些部件可能共享一个可导航目标列表。在这种情况下,您可以创建一个 Destination 部件来保存此信息,并指定 Destination 同时具有图标和文本标签。

接下来,您将评估屏幕尺寸以决定如何显示 UI。

步骤 2:测量

#

Step 2: How to measure screen size

您有两种方法可以确定显示区域的大小:MediaQueryLayoutBuilder

MediaQuery

#

过去,您可能使用 MediaQuery.of 来确定设备屏幕的大小。但是,如今的设备配备了各种尺寸和形状的屏幕,此测试可能会产生误导。

例如,您的应用程序当前可能在一个大屏幕上占据一个小窗口。如果您使用 MediaQuery.of 方法并得出结论认为屏幕很小(实际上,应用程序在一个大屏幕上的一个小窗口中显示),并且您已将应用程序锁定为纵向模式,则会导致应用程序窗口锁定在屏幕中央,周围是黑色。这在大屏幕上绝不是理想的 UI。

请记住,MediaQuery.sizeOf 返回应用程序整个屏幕的当前大小,而不仅仅是单个部件的大小。

您有两种方法可以测量屏幕空间。您可以使用 MediaQuery.sizeOfLayoutBuilder,具体取决于您想要的是整个应用程序窗口的大小,还是更局部的尺寸。

如果您希望部件全屏显示,即使应用程序窗口很小,也请使用 MediaQuery.sizeOf,以便您可以根据应用程序窗口本身的大小选择 UI。在上一节中,您希望将尺寸行为基于整个应用程序的窗口,因此您将使用 MediaQuery.sizeOf

build 方法内部请求应用程序窗口的大小,例如 MediaQuery.sizeOf(context),会导致给定的 BuildContext 在大小属性发生变化时重建。

LayoutBuilder

#

LayoutBuilder 实现了与 MediaQuery.sizeOf 相似的目标,但有一些区别。

LayoutBuilder 不会提供应用程序窗口的大小,而是提供来自父 Widget 的布局约束。这意味着您获得的尺寸信息基于您在小部件树中添加 LayoutBuilder 的特定位置。此外,LayoutBuilder 返回一个 BoxConstraints 对象,而不是 Size 对象,因此您获得的是内容的有效宽度和高度范围(最小值和最大值),而不仅仅是固定大小。这对于自定义小部件很有用。

例如,想象一个自定义小部件,您希望其大小基于专门分配给该小部件的空间,而不是应用程序窗口的整体大小。在这种情况下,使用 LayoutBuilder

步骤 3:分支

#

Step 3: Branch the code based on the desired UI

此时,您必须决定在选择要显示的 UI 版本时使用哪些尺寸断点。例如,Material 布局 指南建议对于宽度小于 600 逻辑像素的窗口使用底部导航栏,对于宽度大于或等于 600 像素的窗口使用导航栏。同样,您的选择不应取决于设备的类型,而应取决于设备的可用窗口大小。

要了解一个在 NavigationRailNavigationBar 之间切换的示例,请查看 使用 Material 3 构建动画响应式应用程序布局

下一页将讨论如何确保您的应用在大屏幕和折叠屏上最佳显示。