若是你对这篇文章感兴趣的话,说明你已经对 Flutter 有了必定的了解,阅读本篇文章你须要记住的最重要的内容就是,Flutter 是能够控制屏幕上的任何一个像素的(由于在 Native 开发里是不能控制状态栏里的像素的,但 Flutter 能够控制状态栏,因此是能够控制屏幕上的任何一个像素)。git
由于能够控制全部的像素,若是咱们想画一个矩形,就能够这样实现:github
Container(
height: 40,
width: 60,
),
复制代码
如今,咱们就用 Container 实现了一个 40 * 60 的矩形,接下来看一下这个矩形在 iPhone 5s (4" Display) 和 iPhone XS Max (6,46" Display) 显示的样子:bash
如上图,你已经注意到,矩形在 iPhone Xs Max 上比 iPhone 5s 要小。less
这是由于 Flutter 无论你的 App 是运行在 iPhone 5s,iPhone Xs Max 或者 13 存的 iPad 上,矩形的大小一直都是 40 x 60。ide
首先,为了便于理解,咱们先用视图的方式来讲明如何解决这个问题,当弄明白了以后,在去写代码。函数
首先,拿出一个空的 view,而后给他加上网格,以下图: ui
而后,咱们把网格的单元成为 'Blocks'。编码
最终,咱们使用 'Blocks' 来划分矩形的宽和高,而后使用 'Blocks' 来表明 view 的大小,假设将宽高都分红 100 分,这样咱们就能够在每一个显示尺寸上拥有一致的 UI。spa
建立一个新的 Dart 文件 size_config.dart,在这个文件里定义一个 SizeConfig 的类。code
import ‘package:flutter/widgets.dart’;
class SizeConfig {}
复制代码
为了使用 Flutter 里的 MediaQueryData 类,MediaQueryData 里包含当前设备的屏幕尺寸信息,咱们须要引入 widgets.dart。
而后在 SizeConfig 里定义以下的属性:
import ‘package:flutter/widgets.dart’;
class SizeConfig {
static MediaQueryData _mediaQueryData;
static double screenWidth;
static double screenHeight;
static double blockSizeHorizontal;
static double blockSizeVertical;
}
复制代码
咱们须要写一个构造函数去初始化这些属性:
class SizeConfig {
static MediaQueryData _mediaQueryData;
static double screenWidth;
static double screenHeight;
static double blockSizeHorizontal;
static double blockSizeVertical;
void init(BuildContext context) {
_mediaQueryData = MediaQuery.of(context);
screenWidth = _mediaQueryData.size.width;
screenHeight = _mediaQueryData.size.height;
blockSizeHorizontal = screenWidth / 100;
blockSizeVertical = screenHeight / 100;
}
}
复制代码
而后就是要在你的 home screen 里初始化 SizeConfig。
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
SizeConfig().init(context);
…
}
}
复制代码
而后咱们就可使用 SizeConfig 里的属性去定义你的 Container 的宽高。
Widget build(BuildContext context) {
return Center(
child: Container(
height: SizeConfig.blockSizeVertical * 20,
width: SizeConfig.blockSizeHorizontal * 50,
color: Colors.orange,
),
);
}
复制代码
最后,在不一样的屏幕上,矩形的宽都是屏幕宽的 50%,矩形的高都是屏幕高的 20%。
下面就是矩形显示在 iPhone 5s 和 iPhone XS Max 的样子。
若是你在 Flutter 开发上已经有了不少经验,你可能已经处理过刘海屏、状态栏、导航栏这些东西。
在 Flutter 中有一个很方便的处理这些东西的 Widget,叫 'SafeArea'。
咱们须要在 SizeConfig 里加入一些其余属性去计算 SafeArea 应占的空间,并从网格中去除它。
class SizeConfig {
static MediaQueryData _mediaQueryData;
static double screenWidth;
static double screenHeight;
static double blockSizeHorizontal;
static double blockSizeVertical;
static double _safeAreaHorizontal;
static double _safeAreaVertical;
static double safeBlockHorizontal;
static double safeBlockVertical;
void init(BuildContext context) {
_mediaQueryData = MediaQuery.of(context);
screenWidth = _mediaQueryData.size.width;
screenHeight = _mediaQueryData.size.height;
blockSizeHorizontal = screenWidth / 100;
blockSizeVertical = screenHeight / 100;
_safeAreaHorizontal = _mediaQueryData.padding.left +
_mediaQueryData.padding.right;
_safeAreaVertical = _mediaQueryData.padding.top +
_mediaQueryData.padding.bottom;
safeBlockHorizontal = (screenWidth -
_safeAreaHorizontal) / 100;
safeBlockVertical = (screenHeight -
_safeAreaVertical) / 100;
}
}
复制代码
这样就可让你高效的适配 UI 而不用担忧 SafaArea。
你可使用一样的网格方法去适配文字,我一般使用 SizeConfig.safeBlockHorizontal 来适配文字,可是你可使用 SizeConfig.blockSizeVertical 来适配。
适配后的效果以下:
本篇文章里全部用到的代码,均可以在下面的 GitHub 里找到: