一、移动端屏幕适配概念
在Flutter应用中一般来说我们是没有用单位的,不像传统的开发用了px,rpx,pt,vw等等,但是在实际的开发过程中移动端不同的屏幕我们都需要做适配。在此,就引出三个概念:逻辑分辨率、物理分辨率 与像素比 。
物理分辨率 :硬件所支持的,即设备分辨率,常常听到的1920,2k屏,物理像素固定,出厂设置好了。
逻辑分辨率(手机屏幕大小) :软件通过算法达到的,Flutter开发中我们用的就是这个逻辑分辨率。
像素比(dpr) :物理像素与逻辑像素的比例,当像素比为1:1时,使用1个物理像素显示1个逻辑像素;当像素比为2:1时,使用4个物理像素(长2倍,宽2倍,乘起来就是4倍)显示1个逻辑像素
获取设备信息(通过MediaQuery)
-
报错分析:首先点击of方法进去
MediaQueryData必须要初始化好,不然你拿到的就是null -
查看MediaQueryData具体是啥
初始化MediaQueryData实际上不是用的构造器函数,而是用的MediaQueryData.formWindow方法 -
具体看看怎么初始化的
只有等这个方法初始化完后,才能调用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,可以显著提升开发效率,让开发者更专注于产品功能的实现。