大屏幕设备
将应用适配到大屏幕时需要注意的事项。
本页面旨在指导您如何优化应用,以改善其在大屏幕上的表现。
Flutter 与 Android 一样,将大屏幕定义为运行 Android 的平板电脑、折叠屏设备和 ChromeOS 设备。Flutter 还将 Web、桌面端和 iPad 定义为大屏幕设备。
使用 GridView 进行布局
#参考以下应用截图。该应用使用 ListView 显示 UI。左图显示的是应用在移动设备上运行的情况。右图显示的是应用在应用本页建议之前,在大屏幕设备上运行的情况。
这种效果并不理想。
Android 大屏幕应用质量指南和 iOS 等效指南均指出,文本和容器都不应占用整个屏幕宽度。如何以自适应方式解决这个问题?
一种常见的解决方案是使用 GridView,详见下一节。
GridView
#您可以使用 GridView 组件将现有的 ListView 转换为尺寸更合理的条目布局。
GridView 与 ListView 组件类似,但 GridView 不仅仅处理线性排列的组件列表,它还可以将组件排列在二维数组中。
GridView 也拥有与 ListView 类似的构造函数。ListView 的默认构造函数对应 GridView.count,而 ListView.builder 则类似于 GridView.builder。
GridView 还有一些用于实现更自定义布局的额外构造函数。要了解更多信息,请访问 GridView API 页面。
例如,如果您的原始应用使用了 ListView.builder,请将其替换为 GridView.builder。如果您的应用包含大量条目,建议使用此 builder 构造函数,以便仅构建当前可见的条目组件。
这两个组件的构造函数中,大多数参数都是相同的,因此替换非常直观。不过,您需要确定如何设置 gridDelegate。
Flutter 提供了功能强大的预制 gridDelegates 供您使用,即:
-
SliverGridDelegateWithFixedCrossAxisCount 允许您为网格分配特定的列数。
-
SliverGridDelegateWithMaxCrossAxisExtent 允许您定义条目的最大宽度。
其他解决方案
#处理这些情况的另一种方法是使用 BoxConstraints 的 maxWidth 属性。这包括以下步骤:
- 用
ConstrainedBox包裹GridView,并为其设置一个最大宽度的BoxConstraints。 - 如果您需要其他功能(例如设置背景颜色),请使用
Container代替ConstrainedBox。
在选择最大宽度值时,请考虑使用 Material 3 布局应用 (Applying layout) 指南中推荐的值。
折叠屏设备
#如前所述,Android 和 Flutter 的设计指南都建议不要锁定屏幕方向,但有些应用仍然锁定了。请注意,在折叠屏设备上运行应用时,这可能会导致问题。
当在折叠屏上运行时,应用在折叠状态下可能看起来正常。但在展开时,您可能会发现应用被“信箱模式”(letterboxed)处理了。
正如 SafeArea & MediaQuery 页面所述,信箱模式意味着应用窗口被锁定在屏幕中央,而窗口周围则是黑边。
为什么会发生这种情况?
当使用 MediaQuery 来计算应用窗口大小时,可能会出现这种情况。当设备折叠时,方向被限制为纵向。在底层,setPreferredOrientations 会导致 Android 使用纵向兼容模式,应用以信箱模式显示。在信箱模式下,MediaQuery 永远无法接收到允许 UI 扩展的更大窗口尺寸。
您可以通过以下两种方式之一来解决此问题:
- 支持所有方向。
- 使用物理显示屏的尺寸。事实上,这是极少数需要使用物理显示尺寸而非窗口尺寸的情况之一。
如何获取物理屏幕尺寸?
您可以使用 Display API,其中包含物理设备的尺寸、像素比和刷新率。
以下示例代码演示了如何获取 Display 对象:
/// AppState object.
ui.FlutterView? _view;
@override
void didChangeDependencies() {
super.didChangeDependencies();
_view = View.maybeOf(context);
}
void didChangeMetrics() {
final ui.Display? display = _view?.display;
}
重点是找到您关注的视图所对应的显示器。这创建了一个前瞻性的 API,旨在处理当前及未来的多显示器和多视图设备。
自适应输入
#增加对更多屏幕的支持,也意味着要扩展输入控制。
Android 指南描述了三个级别的大尺寸设备支持。
Level 3(最低支持级别)包括对鼠标和触控笔输入的支持(Material 3 指南,Apple 指南)。
如果您的应用使用了 Material 3 及其按钮和选择器,那么您的应用已经内置了对各种额外输入状态的支持。
但是,如果您使用了自定义组件呢?请查看 用户输入 页面,获取有关为 组件添加输入支持 的指导。
导航
#在处理各种不同尺寸的设备时,导航可能会带来独特的挑战。通常,您需要根据可用的屏幕空间在 BottomNavigationBar 和 NavigationRail 之间进行切换。
如需更多信息(以及相应的示例代码),请查看 问题:导航栏 (Problem: Navigation rail),这是 Developing Flutter apps for Large screens 文章中的一个章节。