若是你對這篇文章感興趣的話,說明你已經對 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 裏找到: