flutter 屏幕适配分析

218 阅读4分钟

一、移动端屏幕适配概念

在Flutter应用中一般来说我们是没有用单位的,不像传统的开发用了px,rpx,pt,vw等等,但是在实际的开发过程中移动端不同的屏幕我们都需要做适配。在此,就引出三个概念:逻辑分辨率物理分辨率像素比

物理分辨率 :硬件所支持的,即设备分辨率,常常听到的1920,2k屏,物理像素固定,出厂设置好了。
逻辑分辨率(手机屏幕大小) :软件通过算法达到的,Flutter开发中我们用的就是这个逻辑分辨率。
像素比(dpr) :物理像素与逻辑像素的比例,当像素比为1:1时,使用1个物理像素显示1个逻辑像素;当像素比为2:1时,使用4个物理像素(长2倍,宽2倍,乘起来就是4倍)显示1个逻辑像素


获取设备信息(通过MediaQuery)

  1. 报错分析:首先点击of方法进去
    MediaQueryData必须要初始化好,不然你拿到的就是null

  2. 查看MediaQueryData具体是啥
    初始化MediaQueryData实际上不是用的构造器函数,而是用的MediaQueryData.formWindow方法

  3. 具体看看怎么初始化的
    只有等这个方法初始化完后,才能调用MediaQuery.of(context) ,所以要求执行顺序必须是:图五→图一才行,而按照现在的代码顺序却是图一到图五了,所以报错。可以打断点验证整个过程

import 'dart:ui';
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
     //一般希望在应用程序启动就拿到手机的物理分辨率
     final physicalWidth=window.physicalSize.width;
     final physicalHeight=window.physicalSize.height;
     print("手机物理分辨率:$physicalWidth*$physicalHeight");

     //在这里通过媒体查询获取手机屏幕宽高(逻辑分辨率)会报错
      // final screenWidth=MediaQuery.of(context).size.width;
     // final screenHeight=MediaQuery.of(context).size.height;
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      initialRoute: "/", 
      routes: {
        "/": (context) => MyHomePage(title: 'Flutter Demo Home Page'), //注册首页路由
      },
    );
  }
}

解决方案:

     // 获取dpr
     final dpr=window.devicePixelRatio;
    // 通过仿照源码方式获取手机屏幕宽高(逻辑分辨率)
     final screenWidth= physicalWidth/dpr;
     final screenHeight= physicalHeight/dpr;
      // 同理也可以获取状态栏高度等其它参数
     final statusHeight=window.padding.top/dpr;
二、Flutter屏幕适配可以采用小程序的rpx适配

rpx适配原理:

  • 不管是什么屏幕,统一分成750份
  • 在iPhone5上:1rpx = 320/750 = 0.4266 ≈ 0.42px
  • 在iPhone6上:1rpx = 375/750 = 0.5px
  • 在iPhone6plus上:1rpx = 414/750 = 0.552px

算出一个rpx后,再将自己的size和rpx单位相乘即可: 比如100px的宽度:100 * 2 * rpx 在iPhone5上计算出的结果是84px 在iPhone6上计算出的结果是100px 在iPhone6plus上计算出的结果是110.4px

封装一个适配的工具类
import 'dart:ui';

class ScreenUtil {
  static double physicalWidth;
  static double physicalHeight;
  static double screenWidth;
  static double screenHeight;
  static double dpr;
  static double statusHeight;

  static double rpx;

  static void initialize({double standardSize = 750}) {
    // 1.手机的物理分辨率
    physicalWidth = window.physicalSize.width;
    physicalHeight = window.physicalSize.height;

    print("宽高==$physicalWidth --- $physicalHeight");

    // 2.获取dpr
    dpr = window.devicePixelRatio;

    // 3.宽度和高度
    screenWidth = physicalWidth / dpr;
    screenHeight = physicalHeight / dpr;

    // 4.状态栏高度
    statusHeight = window.padding.top / dpr;

    // 5.计算rpx的大小
    rpx = screenWidth / standardSize;
  }

  static px(int size) {
    return rpx *2 * size;
  }
}
工具类的使用

首先需要在入口main.dart初始化

import 'package:flutter/material.dart';
import 'package:flutter_learn/blog/utils/screen_fit.dart';
import 'home/home_page.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    ScreenUtil.initialize();
    return MaterialApp(
      title: 'Flutter widget',
      debugShowCheckedModeBanner:false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

开发小贴士

在实际开发过程中,除了屏幕适配外,iOS开发者还需要考虑应用上架的问题。使用AppUploader这样的iOS开发助手工具可以简化证书管理、应用打包和上传App Store的流程。它提供了可视化的操作界面,让开发者可以更高效地完成应用发布前的准备工作。

文末总结

掌握Flutter屏幕适配是开发高质量跨平台应用的基础。通过本文介绍的rpx适配方案,可以确保应用在不同设备上都能保持良好的显示效果。同时,合理使用开发工具如AppUploader,可以显著提升开发效率,让开发者更专注于产品功能的实现。