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

背景

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

解決方案

從Android中來,到Android中去

Android的適配方案如今相對比較優秀的是頭條這個ide

今日頭條屏幕適配方案終極版正式發佈!函數

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

我理解他的原理就是經過修改系統設置項,把DP值轉化成以寬度或者高度爲基準的度量單位,即寬度或者高度的百分比,而後RD能夠快速把設計稿轉化成UI視圖.佈局

怎麼把這套方案搬到Flutter上

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

修改以下:ui

// 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(),
    );
  }
}
複製代碼

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

擴展方法方案

上面的方法,有個問題是修改了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裏面怎麼寫頂層函數,先這樣寫.code

  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也感知不到.

具體的效果以下:

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

問題

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

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

由於這裏使用的是寬度爲基礎值,可是有些切圖參數是標註的高度,這個時候要麼轉換成相對寬度值, 要麼RD本身估算下.

人物背景圓角都有問題

這裏圓角是切圖畫上去的,外面又有一個本身畫的圓角,兩個圓角不一樣源確定有問題. 要麼直接所有讓UE畫下,這樣開發起來能夠快點. 要麼所有讓RD本身畫,UE只給人偶單圖.

第二手機怎麼有刪格出現

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

總結

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

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

相關文章
相關標籤/搜索