一種低成本的Flutter螢幕適配方案

BestNevermore發表於2020-07-09

背景

老生常談,螢幕適配,UI切圖,視覺還原.

解決方案

從Android中來,到Android中去

Android的適配方案現在相對比較優秀的是頭條這個

今日頭條螢幕適配方案終極版正式釋出!

騷年你的螢幕適配方式該升級了!-今日頭條適配方案

我理解他的原理就是通過修改系統設定項,把DP值轉化成以寬度或者高度為基準的度量單位,即寬度或者高度的百分比,然後RD可以快速把設計稿轉化成UI檢視.

怎麼把這套方案搬到Flutter上

OK,知道原理後,怎麼把這套方案搬到Flutter上面,也就是怎麼修改Flutter的相對畫素單位值?

修改如下:

// main函式
void main() => InnerWidgetsFlutterBinding.ensureInitialized()
  ..attachRootWidget(new MyApp())
  ..scheduleWarmUpFrame();
  

// 具體實現
const double SCREEN_WIDTH = 1242;

double getAdapterRatio() {
  return ui.window.physicalSize.width / SCREEN_WIDTH;
}

Size getScreenAdapterSize() {
  return Size(SCREEN_WIDTH, ui.window.physicalSize.height / getAdapterRatio());
}



class InnerWidgetsFlutterBinding extends WidgetsFlutterBinding {
  static WidgetsBinding ensureInitialized() {
    if (WidgetsBinding.instance == null) InnerWidgetsFlutterBinding();
    return WidgetsBinding.instance;
  }

  @override
  ViewConfiguration createViewConfiguration() {
    return ViewConfiguration(
      size: getScreenAdapterSize(),
      devicePixelRatio: getAdapterRatio(),
    );
  }
}
複製程式碼

一種低成本的Flutter螢幕適配方案

這裡的1242是和UE溝通的標準尺寸. 使用的標準尺寸手機是iPhone 6Plus.

擴充套件方法方案

上面的方法,有個問題是修改了Flutter系統的預設相對畫素單位,我這邊使用沒有問題,但是會導致專案內其他RD開發的時候出現問題. 而我的目的僅僅是想用一個低成本的方案,快速把頁面畫出來.

extension Adapt on Diagnosticable {
  static MediaQueryData mediaQuery = MediaQueryData.fromWindow(window);
  static double _width = mediaQuery.size.width;
  static var _ratio;

  init(int number) {
    int uiwidth = number is int ? number : 1242;
    _ratio = _width / uiwidth;
  }

  px(number) {
    if (!(_ratio is double || _ratio is int)) {
      init(1242);
    }
    return number * _ratio;
  }
}
複製程式碼

這裡使用擴充套件函式,擴充套件到Diagnosticable上,因為還沒找到dart裡面怎麼寫頂層函式,先這樣寫.

  1. 為什麼要用擴充套件函式

和Kotlin一樣,為了不寫工具類

  1. 為什麼要擴充套件到Diagnosticable

因為佈局類裡面的例項,就是Diagnosticable的子類,擴充套件到這上面不用依賴外部類例項.

看個例子就明白了,上面的程式碼用法如下:

                  Positioned(
                    top: 0,
                    child: Image.asset(
                      'assets/images/bg/pay_head.png',
                      width: px(1037),
                    ),
                  ),
                  Positioned(
                    bottom: px(310),
                    child: Container(
                      height: px(796),
                      width: px(1072),
                      child: ...
                    ),
                  ),
複製程式碼

如果使用擴充套件的寫法,這裡直接傳入一個px()函式就行了,裡面的引數是直接從UE的切圖裡面拿出來用的,也不會修改系統預設單位,其他RD也感知不到.

具體的效果如下:

一種低成本的Flutter螢幕適配方案

這樣寫起來就會很快,也能滿足適配要求.

問題

這裡的視覺還沒還原,我這裡先大概評估下方案.

第三部(iphone8)手機高度設定有些問題

因為這裡使用的是寬度為基礎值,但是有些切圖引數是標註的高度,這個時候要麼轉換成相對寬度值, 要麼RD自己估算下.

人物背景圓角都有問題

這裡圓角是切圖畫上去的,外面又有一個自己畫的圓角,兩個圓角不同源肯定有問題. 要麼直接全部讓UE畫下,這樣開發起來可以快點. 要麼全部讓RD自己畫,UE只給人偶單圖.

第二手機怎麼有刪格出現

我也想知道,Android手機怎麼了,按理說這個Google Pixel3配置不差啊.

總結

Android碎片化嚴重,所以Android螢幕適配方案很早就有成熟的東西出來了,對比下這兩個東西的應用場景其實沒什麼大的差別, 那麼人們為什麼會對Flutter適配感到苦惱呢?

正所謂知易而行難,知道了一個知識點只能解決眼前的問題或者更多的只是充當一些談資, 善用知識歸納,內化,運用才能真正幫到自己吧.

相關文章