一种低成本的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适配感到苦恼呢?

正所谓知易而行难,知道了一个知识点只能解决眼前的问题或者更多的只是充当一些谈资, 善用知识概括,内化,运用才能真正帮到本身吧.

相关文章
相关标签/搜索