遇到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的源碼如下:
源碼如下:
主要是createViewConfiguration這個方法,重寫如下:
// 把runApp部分重寫了,如果要獲取虛擬(適配使用的)的寬高,不能直接通過MediaQueryData.fromWindow之類獲取,需要通過真實寬高乘以比例之后才是正確的。
// 好像一般用不到虛擬寬高。
window.physicalSize在哪里會被系統調用呢?
需要關注的如下:
rendering/binding.dart #createViewConfiguration
控件從這里獲得分辨率比例。
gestures/binding.dart #_handlePointerDataPacket
手勢的地方需要用到這個分辨率比例,不然手勢區域會不對。
使用:
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