跳至主要内容

自适应应用的通用方法

那么,您究竟如何着手将一个为传统移动设备设计的应用,使其在各种设备上都呈现出美观的效果?需要哪些步骤?

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 构建动画响应式应用布局

下一页讨论如何确保您的应用在大屏幕和折叠屏设备上都能获得最佳显示效果。