Flutter屏幕适配 - 等比缩放

3,734 阅读2分钟

Flutter屏幕适配

Github项目地址:VPixel

移动端UI适配无非就2种类型

  • 多UI动态响应
  • 单UI等比缩放

这里来聊聊比较常见的 单UI等比缩放 (毕竟省事,手动狗头~~~)

在Flutter里,默认像素单位是dp,由于移动设备 尺寸 & 分辨率 的不一致,导致不同设备有视觉差异,这问题可以通过按设计图绝对宽度基准,进行等比缩放,那么如何实现呢?

适配过程

由于Web,Desktop(PS:都可以手动调整界面尺寸)的正式版发布,使得UI的尺寸变得更多元化

处理流程

  1. 响应UI尺寸的变化

通过注册监听器,可得知UI尺寸的变更

//UI尺寸发生变化时,会回调 WidgetsBindingObserver 的 didChangeMetrics 函数
WidgetsBinding.instance.addObserver(WidgetsBindingObserver observer);
  1. 更改缩放比

由 didChangeMetrics 函数得知UI尺寸变更,这里作出变更缩放比处理

//获取最新UI尺寸数据
final data = MediaQueryData.fromWindow(WidgetsBinding.instance?.window);
//缩放比 = data.size.width / 设计图尺寸;
  1. 通知UI重建

最后通过setState函数进行通知刷新

实现方式可看项目源码,或者后期分解~~~

使用方式

  1. 导入项目
dependencies:
  # 虚拟像素
  vpixel:
    git:
      url: https://github.com/XiaoBaiCZ/vPixel.git
      ref: stable
  1. 使用VPixel包住需要缩放的Widget,推荐 入口Widget(全局通用)
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    //入口设置VPixel
    return VPixel(
      //设计稿宽度尺寸
      designWidth: 750,
      builder: (ctx) {
        //原入口Widget
        //App范围内都能使用vpx,如Body
        return MaterialApp(
          home: Scaffold(
            body: Body(),
          ),
        );
      },
    );
  }
}

//App范围内可用vpx填写设计稿尺寸
class Body extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Stack(
      alignment: Alignment.center,
      children: [
        //3等分方块
        //App范围内可用vpx填写设计稿尺寸
        Positioned(
          top: 0,
          left: 0,
          child: Container(color: Colors.red, width: 250.vpx, height: 250.vpx,),
        ),
        Positioned(
          top: 0,
          child: Container(color: Colors.green, width: 250.vpx, height: 250.vpx,),
        ),
        Positioned(
          top: 0,
          right: 0,
          child: Container(color: Colors.blue, width: 250.vpx, height: 250.vpx,),
        ),
        //2等分方块
        Positioned(
          bottom: 0,
          left: 0,
          child: Container(color: Colors.yellow, width: 375.vpx, height: 375.vpx,),
        ),
        Positioned(
          bottom: 0,
          right: 0,
          child: Container(color: Colors.orange, width: 375.vpx, height: 375.vpx,),
        ),
      ],
    );
  }
}
  1. 效果图 5EBB03B8-D00D-436A-8155-73303A6334FC.png

6A8CD3B3-6FDD-4BB7-AFB6-E7FA14BBEBDF.png