flutter屏幕適配


現在的手機品牌和型號越來越多,導致我們平時寫布局的時候會在個不同的移動設備上顯示的效果不同,

比如我們的設計稿一個View的大小是300px,如果直接寫300px,可能在當前設備顯示正常,但到了其他設備可能就會偏小或者偏大,這就需要我們對屏幕進行適配。

安卓原生的話有自己的適配規則,可以根據不同的尺寸建立不同的文件夾,系統會根據當前的設備尺寸取對應的大小的布局。而flutter本身並沒有適配規則,而原生的又比較繁瑣,這就需要我們自己去對屏幕進行適配。

點擊直達github地址 如果有幫助,請給我個star

flutter_ScreenUtil

flutter 屏幕適配方案

github: github.com/OpenFlutter…

csdn博客 工具 介紹: blog.csdn.net/u011272795/…

使用方法:

安裝依賴:

安裝之前請查看最新版本

dependencies: flutter: sdk: flutter # 添加依賴 flutter_screenutil: ^0.3.0 復制代碼

在每個使用的地方導入包:

import 'package:flutter_screenutil/flutter_screenutil.dart'; 復制代碼

初始化設置尺寸

在使用之前請設置好設計稿的寬度和高度,傳入設計稿的寬度和高度(單位px) 一定在MaterialApp的home中的頁面設置,以保證在每次使用之前設置好了適配尺寸:

//設置適配尺寸 (填入設計稿中設備的屏幕尺寸) 假如設計稿是按iPhone6的尺寸設計的(iPhone6 750*1334) ScreenUtil.instance = ScreenUtil(width: 750, height: 1334)..init(context); 復制代碼

使用:

適配尺寸:

//傳入設計稿的px尺寸: 適配后的寬度width: ScreenUtil().setWidth(540), 適配后的高度height: ScreenUtil().setHeight(200), 高度也根據setWidth來做適配可以保證不變形 例如: Container( width: ScreenUtil().setWidth(375), height: ScreenUtil().setHeight(200), ), 復制代碼

適配字體:

ScreenUtil().setSp(28) //傳入字體大小,根據系統的“字體大小”輔助選項來進行縮放 ScreenUtil().setSp(28false) //傳入字體大小,不會根據系統的“字體大小”輔助選項來進行縮放 for example: Text( 'My font size is 28px and will not change with the system.', style: TextStyle( color: Colors.black, fontSize: ScreenUtil().setSp(28, false) ) ), 復制代碼

其他相關api:

ScreenUtil.pixelRatio //設備的像素密度 ScreenUtil.screenWidth //設備寬度 ScreenUtil.screenHeight //設備高度 ScreenUtil.bottomBarHeight //底部安全區距離,適用於全面屏下面有按鍵的 ScreenUtil.statusBarHeight //狀態欄高度 劉海屏會更高 單位px ScreenUtil.textScaleFactory //系統字體縮放比例 ScreenUtil().scaleWidth //寬度相對於設計稿放大的倍數 ScreenUtil().scaleHeight //高度相對於設計稿放大的倍數 復制代碼
//導入 import 'package:flutter_screenutil/flutter_screenutil.dart'; ... @override Widget build(BuildContext context) { //設置適配尺寸 (填入設計稿中設備的屏幕尺寸) 假如設計稿是按iPhone6的尺寸設計的(iPhone6 750*1334) ScreenUtil.instance = ScreenUtil(width: 750, height: 1334)..init(context); print('設備寬度:${ScreenUtil.screenWidth}'); //Device width print('設備高度:${ScreenUtil.screenHeight}'); //Device height print('設備的像素密度:${ScreenUtil.pixelRatio}'); //Device pixel density print( '底部安全區距離:${ScreenUtil.bottomBarHeight}'); //Bottom safe zone distance,suitable for buttons with full screen print( '狀態欄高度:${ScreenUtil.statusBarHeight}px'); //Status bar height , Notch will be higher Unit px print( '寬度相對於設計稿放大的倍數:${ScreenUtil().scaleWidth}'); //The width is enlarged relative to the design draft print( '高度相對於設計稿放大的倍數:${ScreenUtil().scaleHeight}'); //The height is enlarged relative to the design draft print('系統的字體縮放比例:${ScreenUtil.textScaleFactory}'); return new Scaffold( appBar: new AppBar( title: new Text(widget.title), ), body: new Center( child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ Row( children: <Widget>[ Container( width: ScreenUtil().setWidth(375), height: ScreenUtil().setHeight(200), color: Colors.red, child: Text( 'My width:${ScreenUtil().setWidth(375)}dp', style: TextStyle( color: Colors.white, fontSize: ScreenUtil().setSp(28, false)), ), ), Container( width: ScreenUtil().setWidth(375), height: ScreenUtil().setHeight(200), color: Colors.blue, child: Text('My width:${ScreenUtil().setWidth(375)}dp', style: TextStyle( color: Colors.white, fontSize: ScreenUtil().setSp(28, false))), ), ], ), Text('Device width:${ScreenUtil.screenWidth}px'), Text('Device height:${ScreenUtil.screenHeight}px'), Text('Device pixel density:${ScreenUtil.pixelRatio}'), Text('Bottom safe zone distance:${ScreenUtil.bottomBarHeight}px'), Text('Status bar height:${ScreenUtil.statusBarHeight}px'), Text( 'Width is enlarged relative to the design draft:${ScreenUtil().scaleWidth}', textAlign: TextAlign.center, ), Text( 'Height is enlarged relative to the design draft:${ScreenUtil().scaleHeight}', textAlign: TextAlign.center, ), SizedBox( height: ScreenUtil().setHeight(200), ), Text('System font scaling:${ScreenUtil.textScaleFactory}'), Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Text( '我的文字大小是28px,不會隨着系統的文字大小變化', style: TextStyle( color: Colors.black, fontSize: ScreenUtil().setSp(28, false))), Text('我的文字大小是28px,會隨着系統的文字大小變化', style: TextStyle( color: Colors.black, fontSize: ScreenUtil().setSp(28))), ], ) ], ), ), ); } 復制代碼

使用示例:

example demo

效果:

適配原理

說一下適配方案, 比如我們設計師設計的UI是根據Iphone6來做的,我們知道 iPhone6的分辨率是750*1334(px), 又或者是根據hdpi的設備來設計的UI,我們知道hdpi的 Android 設備是 (240 dpi),像素密度是1.5,即hdpi設備的分辨率寬度是320px, 總之,無論設計稿的單位是px,或者是dp,我們都能夠轉換成px. 那么我們如果根據px來適配,ios和 android 就都可以兼容了.

假設,我們的設計稿手機是1080 1920 px. 設計稿上有一個540 960 的組件, 即寬度和寬度是手機的一半. 如果我們直接寫的時候組件的尺寸這么定義,在其他尺寸的設備上未必是一半,或多,或少. 但是我們可以按比例來看,即我們要實現的寬度是實際設備的一半. 那么假設我們設備的寬度是deviceWidth和deviceHeight , 我們要寫的組件大小為: 寬:(540/1080)*deviceWidth,高度: (960/1920)*deviceHeight.

通過這個公式我們可以發現,我們要寫的組件寬度就是設計稿上的尺寸width*(deviceWdith/原型設備寬度).那么每次我們寫ui的時候,只要直接哪來設計稿的尺寸*(deviceWdith/設備原型)寬度即可.

原理就是先獲取,實際設備與原型設備的尺寸比例. 首先flutter獲取設備的尺寸的代碼是:

以下數據為我的手機數據: import 'dart:ui'; //因為window是dart:ui中提供的,所以需要引入這個包. window.physicalSize //Size(1080.0, 1794.0) 單位px width = window.physicalSize.width //寬度 height = window.physicalSize.height //高度 //使用這個方法則無需引入包 MediaQuery.of(context).size //Size(411.4, 683.4) 單位:dp widhtDp = MediaQuery.of(context).size.width //寬度 411.4 heightDp = MediaQuery.of(context).size.height //高度 683.4 復制代碼

設計稿單位是px,且尺寸為1080*1920 px 時:

scaleWidth = width / 1080; scaleHeight = height / 1920; 復制代碼

那么我們要寫尺寸為500 100控件的寬度就是 500 scaleWidth .100*scaleHeigh ,注意這時單位是px,flutter中默認組件尺寸單位都是dp,我們還要進行px->dp的操作.除以像素密度就好了. flutter獲取像素密度的方法:

MediaQuery.of(context).devicePixelRatio window.physicalSize 復制代碼

上面兩種方法得到的是一樣的結果,但是window對象來自dart:ui,所以我們引入這個包:

import 'dart:ui';

設計稿單位是dp,且尺寸為360*640 dp 時:

scaleWidth = widhtDp / 360; scaleHeight = heightDp / 640; 那么我們要寫尺寸為500*100控件的寬度就是 500*scaleWidth .100*scaleHeigh 復制代碼

字體大小適配

setSp(int fontSize, [allowFontScaling = true]) => allowFontScaling ? setWidth(fontSize) * _textScaleFactor : setWidth(fontSize); 復制代碼

第一個參數為設計稿中字體的大小,單位px, 第二個參數可選,為控制字體是否要根據系統的“字體大小”輔助選項來進行縮放。默認值為true。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM