Flutter 屏幕適配

遇到ue為了保證雙端產生的物理效果一致的問題,可能會為雙端配置不同的虛擬像素,因為android和ios的像素密度是不同的。如果遇到這種問題,可以使用以下方式來進行整體適配,這個方案的原理是基于根據平臺動態縮放整個頁面,這樣,在具體頁面里使用時,只要寫一端的值就可以了,對開發更加友好。

手機基本都是基于寬度為標準,適配高度,因為手機是上下滑動的。

一些尺寸原理:

關注在window.dart里面兩個變量:

// 分辨率比例,iOS的@3X,Android中的2.75(density),

devicePixelRatio

// 物理尺寸 比如iPhone6/7/8Plus 1242?×?2208,紅米note5 1080 × 2160

physicalSize

比如有一個橙色的矩形,那么這個矩形在iPhone6Plus上,顯示為(600px,30px)的矩形,在紅米note5上,顯示為(550px,27px)的矩形。

也就是說,在Flutter的Widget中,我們寫的寬高,最后在顯示的時候會被系統自動乘上window.devicePixelRatio。 *** 這里很重要,后面會用到。

Container(

? width: 200,

? height: 10,

? color: Colors.orange,

),

方案一 1242:

原理:

我們動態計算把UE設計稿寬度和每個屏幕的寬度相除取比例,然后把UE設計稿的尺寸動態都乘上這個比例,就得到每個屏幕的適配值。

具體實現:


通過擴充num類(int double的父類),將設計稿標準寬度(如1242)和真實手機屏幕寬度相除,得到縮放比例。使用的時候通過num的擴展函數.px 算出真實值。

優缺點:

1、使用簡單、原理簡單,初始化就一行。

2、可以兼容不同設計稿,如果工程有歷史原因,有些歷史頁面或者不同設計師沒有按照規范出圖,一樣可以適配。

3、使用的時候數字都要加上.px 后綴,有人可能會感到不適。

pub地址:https://pub.dev/packages/pixel_adapter


方案二 414:

通過設置一個類似BaseView的形式,去掉num的擴展,把View里面的所有數字都通過底層進行ratio轉換。

然后我們發現底層的Widget和StatelessWidget、StatefulWidget都沒有寬高屬性。

因為Flutter里面萬物皆Widget,一些比如Text,GestureDetector是沒有寬高的。

記得我們上面說的在Flutter的Widget中,我們寫的寬高,最后在顯示的時候會被系統自動乘上window.devicePixelRatio。

既然我們沒有BaseView,那么我們是否可以修改 window.devicePixelRatio像素密度

我們設想:基于修改系統的縮放值來實現改變系統繪制的大小。

我們找了一些網絡資料,發現我們需要重寫WidgetsFlutterBinding,從runApp入口修改。runApp的源碼如下:

源碼如下:

runApp的源碼

主要是createViewConfiguration這個方法,重寫如下:

createViewConfiguration

// 把runApp部分重寫了,如果要獲取虛擬(適配使用的)的寬高,不能直接通過MediaQueryData.fromWindow之類獲取,需要通過真實寬高乘以比例之后才是正確的。

// 好像一般用不到虛擬寬高。

window.physicalSize在哪里會被系統調用呢?

需要關注的如下:

rendering/binding.dart #createViewConfiguration

控件從這里獲得分辨率比例。

gestures/binding.dart #_handlePointerDataPacket

手勢的地方需要用到這個分辨率比例,不然手勢區域會不對。

GestureBinding

使用:

InnerWidgetsFlutterBinding.initPixel(1242, 3);

InnerWidgetsFlutterBinding.ensureInitialized()

? ..attachRootWidget(MyApp())

? ..scheduleWarmUpFrame();

優缺點:

1、不能動態設置ratio值,即不能根據屏幕寬高和設計稿的比例獲取真實比例(不能兼容不同設計稿)

2、用法簡單:在使用是沒有任何要求,與flutter原生相同。開發人員無感知

3、因為手動重寫了gestures/binding.dart的一些方法,隨著Flutter版本的升級,需要不斷修改InnerWidgetsFlutterBinding的代碼。

pub地址:https://pub.dev/packages/pixel_fix


參考文檔

Flutter框架分析之初始化https://www.cnblogs.com/lxlx1798/articles/11099164.html

從Flutter的Binding們說起:http://www.lxweimin.com/p/79844d54c2c7

深入Flutter的Rendering層:https://blog.csdn.net/scnuxisan225/article/details/104128284

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容