目前移動端的設備已經很是多,而且不一樣的設備手機屏幕也不相同。前端
目前作移動端開發都要針對不一樣的設備進行必定的適配,不管是移動原生開發、小程序、H5頁面。vue
Flutter中如何針對不一樣的手機屏幕來進行適配呢?咱們一塊兒來聊聊這個話題。web
在進行Flutter開發時,咱們一般不須要傳入尺寸的單位,那麼Flutter使用的是什麼單位呢?算法
在Flutter開發中,咱們使用的是對應的邏輯分辨率小程序
獲取屏幕上的一些信息,能夠經過MediaQuery:api
// 1.媒體查詢信息
final mediaQueryData = MediaQuery.of(context); // 2.獲取寬度和高度 final screenWidth = mediaQueryData.size.width; final screenHeight = mediaQueryData.size.height; final physicalWidth = window.physicalSize.width; final physicalHeight = window.physicalSize.height; final dpr = window.devicePixelRatio; print("屏幕width:$screenWidth height:$screenHeight"); print("分辨率: $physicalWidth - $physicalHeight"); print("dpr: $dpr"); // 3.狀態欄的高度 // 有劉海的屏幕:44 沒有劉海的屏幕爲20 final statusBarHeight = mediaQueryData.padding.top; // 有劉海的屏幕:34 沒有劉海的屏幕0 final bottomHeight = mediaQueryData.padding.bottom; print("狀態欄height: $statusBarHeight 底部高度:$bottomHeight"); 複製代碼
獲取一些設備相關的信息,可使用官方提供的一個庫:數據結構
dependencies:
device_info: ^0.4.2+1 複製代碼
假如咱們有下面這樣一段代碼:app
class HYHomePage extends StatelessWidget {
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("首頁"), ), body: Center( child: Container( width: 200, height: 200, color: Colors.red, alignment: Alignment.center, child: Text("Hello World", style: TextStyle(fontSize: 30, color: Colors.white),), ), ), ); } } 複製代碼
上面的代碼在不一樣屏幕上會有不一樣的表現:less
很明顯,若是按照上面的規則,在iPhone5上面,尺寸過大,在iPhone6plus上面尺寸太小編輯器
在開發中,咱們應該能夠根據不一樣的屏幕來完成尺寸的縮放
在前端開發中,針對不一樣的屏幕常見的適配方案有下面幾種:
這裏我採用小程序的rpx來完成Flutter的適配
小程序中rpx的原理是什麼呢?
那麼咱們就能夠經過上面的計算方式,算出一個rpx,再將本身的size和rpx單位相乘便可:
咱們本身來封裝一個工具類:
class HYSizeFit {
static MediaQueryData _mediaQueryData; static double screenWidth; static double screenHeight; static double rpx; static double px; static void initialize(BuildContext context, {double standardWidth = 750}) { _mediaQueryData = MediaQuery.of(context); screenWidth = _mediaQueryData.size.width; screenHeight = _mediaQueryData.size.height; rpx = screenWidth / standardWidth; px = screenWidth / standardWidth * 2; } // 按照像素來設置 static double setPx(double size) { return HYSizeFit.rpx * size * 2; } // 按照rxp來設置 static double setRpx(double size) { return HYSizeFit.rpx * size; } } 複製代碼
初始化HYSizeFit類的屬性:
class HYHomePage extends StatelessWidget {
@override Widget build(BuildContext context) { // 初始化HYSizeFit HYSizeFit.initialize(context); return null; } } 複製代碼
使用rpx來完成屏幕適配:
class HYHomePage extends StatelessWidget {
@override Widget build(BuildContext context) { HYSizeFit.initialize(context); return Scaffold( appBar: AppBar( title: Text("首頁"), ), body: Center( child: Container( width: HYSizeFit.setPx(200), height: HYSizeFit.setRpx(400), color: Colors.red, alignment: Alignment.center, child: Text("Hello World", style: TextStyle(fontSize: HYSizeFit.setPx(30), color: Colors.white),), ), ), ); } } 複製代碼
咱們來看一下實現效果:
若是每次咱們須要將如今的寬度或者高度,去使用HYSizeFit.setPx(200)或者HYSizeFit.setRpx(400)相似的方式去適配,顯然看起來很是麻煩。
有沒有更好的方案能夠實現了?好比 200.px或者400.rpx,很是的清晰簡潔
固然能夠,咱們須要依賴Dart語言的一個特性:extension
好比咱們如今對String類型擴展:
// 步驟一:擴展代碼
extension NumberParsing on String { int parseInt() { return int.parse(this); } // ··· } // 步驟二:調用代碼 // 導入擴展類對應的模塊 import 'string_apis.dart'; // 使用裏面的方法 print('42'.padLeft(5)); // 使用String原有的方法 print('42'.parseInt()); // 使用String擴展的方法 複製代碼
顯然,數字(好比200、200.0)有對應的包裝類int、double,咱們能夠對其進行擴展:
1.對int類型擴展
import '../shared/size_fit.dart';
extension IntFit on int { double get px { return HYSizeFit.setPx(this.toDouble()); } double get rpx { return HYSizeFit.setRpx(this.toDouble()); } } 複製代碼
2.對double類型擴展
import '../shared/size_fit.dart';
extension DoubleFit on double { double get px { return HYSizeFit.setPx(this); } double get rpx { return HYSizeFit.setRpx(this); } } 複製代碼
如何使用了?
import './extension/double_extension.dart';
import './extension/int_extension.dart'; print(200.px); // 在不一樣屏幕下200px是不一樣的值 print(400.rpx); // 在不一樣屏幕下400rpx是不一樣的值 複製代碼
備註:全部內容首發於公衆號,以後除了Flutter也會更新其餘技術文章,TypeScript、React、Node、uniapp、mpvue、數據結構與算法等等,也會更新一些本身的學習心得等,歡迎你們關注