IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 极其简单的Flutter 屏幕适配 -> 正文阅读

[移动开发]极其简单的Flutter 屏幕适配

A low-cost Flutter screen adaptation solution(一个极低成本的 Flutter 屏幕适配方案)

一 概述

由于 Flutter 的应用场景很多,不只是 android 还有 ios 以及 web,现在的手机品牌和型号越来越多,导致我们平时写布局的时候会在个不同的移动设备上显示的效果不同,今天介绍一种方案,可以是一个低成本,但是 100% 还原UI的一种办法,无需使用工具类或者是扩展函数去 转换,直接写 UI设计图给的大小即可

github 欢迎 star

flutter_autosize_screen 欢迎 star 以及 提出建议

三 先看效果

IOS

iPhone 8 ------------------------------- iPhone 11 :
iPhone 12 pro max --------------------- ipad air :

android 图

768x1280-320dpi----------10801920-420dpi----------1440x2560-560dpi

web 图

随着拉长屏幕 ,慢慢的 宽度会大于高度,当大于的时候 ,会以 高度 为 基准。

三 使用

3.1 引用

flutter_autosize_screen: ^{LAST_VERSION}

3.2 初始化

  1. 在main方法的第一行就初始化,下面的基准一般以宽度为基准,直接写Ui设计图的宽度尺寸,如果是横屏的状态的 下面的 360 就是以高度为基准
void main() {
  // 设置基准
  AutoSizeUtil.setStandard(360);

  // 使用 runAutoApp 来代替 runApp
  // import 'package:flutter_autosize_screen/binding.dart';
  runAutoApp(const MyApp());

}

  1. 替换根 MaterialApp 的 MediaQuery
MaterialApp(
      title: 'Autosize Demo',
      /// 替换,这样可以在以后 使用 MediaQuery.of(context) 得到 正确的Size
      builder: AutoSizeUtil.appBuilder,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        body: HomePage(),
      ),
    )

  1. 获取Size
AutoSizeUtil.getScreenSize()
//或者
MediaQuery.of(context).size
  1. 直接按照设计图的尺寸写即可
Container(
    alignment: Alignment.center,
    height: 60,
    width :60,
    color: Colors.redAccent,
    child: Text(
      "直接按照设计图写尺寸",
    ),
  )
  1. 切记
    不能使用 window 获取 size 或者是 获取 MediaQuery

    window.physicalSize

    MediaQueryData.fromWindow(window)

四 原理

4.1 Flutter 入口 runApp(Widget app)

当我们调用 runApp 的时候,会做三件事请 1.实例化WidgetsFlutterBinding类,2.创建组件树attachRootWidget(app),3.启动预热帧scheduleWarnUpFrame()。

void runApp(Widget app) {
  WidgetsFlutterBinding.ensureInitialized()
    ..scheduleAttachRootWidget(app)
    ..scheduleWarmUpFrame();
}

4.2 WidgetsFlutterBinding

正如此类的名字一样, WidgetsFlutterBinding正是绑定widget 框架和Flutter engine的桥梁,WidgetsFlutterBinding继承自BindingBase 并混入了很多Binding

class WidgetsFlutterBinding extends BindingBase with GestureBinding, SchedulerBinding, ServicesBinding, PaintingBinding, SemanticsBinding, RendererBinding, WidgetsBinding {
  static WidgetsBinding ensureInitialized() {
    if (WidgetsBinding.instance == null)
      WidgetsFlutterBinding();
    return WidgetsBinding.instance!;
  }
}

4.2.1 我们看看各个混入的 Binding的作用

  • GestureBinding:提供了window.onPointerDataPacket 回调,绑定Framework手势子系统,是Framework事件模型与底层事件的绑定入口。
  • ServicesBinding:提供了window.onPlatformMessage 回调, 用于绑定平台消息通道(message channel),主要处理原生和Flutter通信。
  • SchedulerBinding:提供了window.onBeginFrame和window.onDrawFrame回调,监听刷新事件,绑定Framework绘制调度子系统。
  • PaintingBinding:绑定绘制库,主要用于处理图片缓存。
  • SemanticsBinding:语义化层与Flutter engine的桥梁,主要是辅助功能的底层支持。
  • RendererBinding: 提供了window.onMetricsChanged 、window.onTextScaleFactorChanged 等回调。它是渲染树与Flutter engine的桥梁。
  • WidgetsBinding:提供了window.onLocaleChanged、onBuildScheduled 等回调。它是Flutter widget层与engine的桥梁。

4.3 重点是 RendererBinding

初始化了 第一个 RenderView 。这个RenderView就是渲染树(render tree)的根节点,其次 是 渲染屏幕,里面有个重要的方法 createViewConfiguration,看 源码上面的注释
Bindings 可以重写这个方法来更改大小或设备像素,所以我们可以从这个上面入手

void initRenderView() {
    assert(!_debugIsRenderViewInitialized);
    assert(() {
      _debugIsRenderViewInitialized = true;
      return true;
    }());
    renderView = RenderView(configuration: createViewConfiguration(), window: window);
    renderView.prepareInitialFrame();
  }

/// Bindings can override this method to change what size or device pixel
/// ratio the [RenderView] will use. For example, the testing framework uses
/// this to force the display into 800x600 when a test is run on the device
/// using `flutter run`.
ViewConfiguration createViewConfiguration() {
    final double devicePixelRatio = window.devicePixelRatio;
    return ViewConfiguration(
      size: window.physicalSize / devicePixelRatio,
      devicePixelRatio: devicePixelRatio,
    );
}

4.4 写个类 AutoWidgetsFlutterBinding 继承 WidgetsFlutterBinding

重写 createViewConfiguration 的方法,更改 devicePixelRatio 以及 屏幕的Size,如下,因为调整了 devicePixelRatio,所以对于 Event 事件,需要额外对事件的坐标进行对应比例的转换,这个就看源码就可以了

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

  @override
  ViewConfiguration createViewConfiguration() {
    return ViewConfiguration(
      size: AutoSizeUtil.getSize(),
      devicePixelRatio: AutoSizeUtil.getDevicePixelRatio(),
    );
  }

五 感谢

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-08-17 15:30:31  更:2021-08-17 15:31:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 10:19:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码