fl_responsive_guide
基础
为了理解响应式构建,我们需要回顾一下 Material Design 提到的一些概念,例如:布局解剖:https://material.io/design/layout/understanding-layout.html 在本节中,我们将了解...的定义
应用栏:https://material.io/design/layout/understanding-layout.html
设备断点:https://material.io/design/layout/responsive-layout-grid.html
导航区域:https://material.io/design/layout/understanding-layout.html
列、间隙、边距:https://material.io/design/layout/responsive-layout-grid.html
在研究了以上信息后,我们会发现构建响应式界面需要基于以上参数进行工作。在这里,我们将有一个名为*ResponsiveGuide*的类。*ResponsiveGuide*是一个*InheritedWidget*,它允许其下方的 widget 能够接收到关于*FlDesignConfig*构建配置的更改信息。
每个断点都有一个单独的配置来确定需要时的渲染类型。UI 渲染参数如下。
final FlSize margin; -> Dùng xác định cho margin của Body
final FlSize body; -> Dùng xác định width của body
final int layoutColumns; -> config cho số column trong body
final double gutters; ->
final DeviceTarget deviceTarget; -> config xem giao diện của breakpoint này sẽ render cho device nào.
final double? navigationRailWidth;
final double appbarHeight;
final double drawerWidth;
final double tabBarHeight;
其中,我们需要注意*FlSize*。这个类将允许我们确定何时需要声明特定大小,何时需要让它根据屏幕自动缩放。
abstract class FlSize {
FlSize();
factory FlSize.size(double size) {
return FlSizeNumber(size);
}
factory FlSize.scale() {
return FlSizeScale();
}
}
class FlSizeNumber extends FlSize {
final double number;
FlSizeNumber(this.number);
}
class FlSizeScale extends FlSize {}
实现
应用程序的断点系统
基本上,构建响应式应用程序就是确定屏幕类型(由断点确定)。根据当前断点决定要构建的界面。因此,我们需要为应用程序确定断点。
以下是 Material Design 的断点划分指南
| 屏幕尺寸 | 外边距 | 主体 | 布局列 |
|---|---|---|---|
| 0-599dp | 16dp | 缩放 | 4 |
| 600-904 | 32dp | 缩放 | 8 |
| 905-1239 | 缩放 | 840dp | 12 |
| 1240-1439 | 200dp | 缩放 | 12 |
| 1440+ | 缩放 | 1040 | 12 |
应用示例
breakpointSystems: {
600: FlDesignConfig(
body: FlSize.scale(),
margin: FlSize.size(0),
appbarHeight: 56,
deviceTarget: DeviceTarget.mobile),
900: FlDesignConfig(
body: FlSize.scale(),
margin: FlSize.size(0),
gutters: 12,
appbarHeight: 56,
deviceTarget: DeviceTarget.tablet),
double.maxFinite: FlDesignConfig(
body: FlSize.size(621),
margin: FlSize.scale(),
gutters: 24,
appbarHeight: 80,
deviceTarget: DeviceTarget.desktop)
}
有了这个*breakpointSystems*,我们可以看到应用程序被划分为三种屏幕类型:
1:0 < 宽度 < 600 => 此类型被设备识别为*移动设备*,*应用栏*的高度为 56dp
2:600 <= 宽度 < 900 => 此类型被设备识别为*平板电脑*,*应用栏*的高度为 56dp,间隙为 12dp
3:宽度 >= 900 => 此类型被设备识别为*桌面设备*,*应用栏*的高度为 80dp,间隙为 24dp
创建支持响应式构建的包装器 widget
确定应用程序的断点后,widget 在渲染时将根据哪个断点来确定它们需要渲染的 UI。
为了实现这一点,我们将需要两个类:
-
*ResponsiveGuideWrapper*它就像一个响应式布局的 Provider。它允许其子 widget 确定当前用于渲染的断点是什么。
-
*ResponsiveGuideConsumerWidget*一个 Consumer Widget,允许子 widget 知道当前渲染的参数是什么。
示例
Widget build(BuildContext context) {
return ResponsiveGuideWrapper(
breakpointSystems: {
600: FlDesignConfig(
body: FlSize.scale(),
margin: FlSize.size(0),
appbarHeight: 56,
deviceTarget: DeviceTarget.mobile),
900: FlDesignConfig(
body: FlSize.scale(),
margin: FlSize.size(0),
gutters: 12,
appbarHeight: 56,
deviceTarget: DeviceTarget.tablet),
double.maxFinite: FlDesignConfig(
body: FlSize.size(621),
margin: FlSize.scale(),
gutters: 12,
appbarHeight: 56,
deviceTarget: DeviceTarget.desktop)
},
child: Application(),
);
}
}
使用
body: ResponsiveGuideConsumerWidget(
builder: (context, designInfo) {
switch (designInfo.deviceTarget) {
case DeviceTarget.mobile:
return Center(
child: Text('Mobile App'),
);
case DeviceTarget.tablet:
return Center(
child: Text('Tablet App'),
);
case DeviceTarget.desktop:
return Center(
child: Text('Desktop App'),
);
}
},
)


