现在我们来搞几个模拟器 iphone 5 6 6+ 其他的东西来使用这个
class HYHomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("物理宽度高度 ${HYSizeFit.physicalWidth} * ${HYSizeFit.physicalHeight}");
return Scaffold(
appBar: AppBar(
title: Text("title")
),
body: Center(
child: Container(
width: 200,
height: 200,
color: Colors.red,
child: Text("hello world", style: TextStyle(fontSize: 20)),
)
),
);
}
}
image
但是我们这只是在小屏幕的iphone上面可以放下
如果我们到 iphone5上面说不定就不行了 他是比较小的
如果我们这里也给他搞一个200 * 200 说不定就不行了 这个时候 如果站的比较多了 这个时候 可能就会报一些错了
所以我们希望你在iphone5 上面 放的小一点 然后再iphone 6 + 上面放的大一点
但是现在如果跑在这些机器上面那他们的距离因该都是200 * 200 这个大小现在是写死的
其实在前端里面对这个东西的适配已经有很多的经验了 所以我们这里借助前端的方案来适配
前端的方案有三种
rem
vw vh
rpx
import 'dart:ui';
class HYSizeFit {
static double physicalWidth;
static double physicalHeight;
static double screenWidth;
static double screenHeight;
static double dpr;
static double statusHeight;
static double rpx;
static void initialize() {
// 1. 手机的物理分辨率
physicalWidth = window.physicalSize.width; // 拿到物理的宽度
physicalHeight = window.physicalSize.height;
// 2. 求出dpr
dpr = window.devicePixelRatio;
// 3. 求出逻辑的宽高
screenWidth = physicalWidth / dpr;
screenHeight = physicalHeight /dpr;
// 4. 状态栏高度
statusHeight = window.padding.top / dpr;
// 5. 计算rpx
rpx = screenWidth / 750;
}
}
其实就是 逻辑宽度和750 的商
然后再其他的地方使用
class HYHomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("物理宽度高度 ${HYSizeFit.physicalWidth} * ${HYSizeFit.physicalHeight}");
return Scaffold(
appBar: AppBar(
title: Text("title")
),
body: Center(
child: Container(
width: 200 * HYSizeFit.rpx,
height: 200 * HYSizeFit.rpx,
color: Colors.red,
child: Center(
child: Text("hello world", style: TextStyle(fontSize: 20))
),
)
),
);
}
}
当然后面我们有更好的适配的写法
但是你注意一个问题就是 小程序里面 我们的是除以 750 不是375 所以我们的所有的东西 都要翻倍
class HYHomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("物理宽度高度 ${HYSizeFit.physicalWidth} * ${HYSizeFit.physicalHeight}");
return Scaffold(
appBar: AppBar(
title: Text("title")
),
body: Center(
child: Container(
width: 400 * HYSizeFit.rpx,
height: 400 * HYSizeFit.rpx,
color: Colors.red,
child: Center(
child: Text("hello world", style: TextStyle(fontSize: 40 * HYSizeFit.rpx))
),
)
),
);
}
}
这样我们的大小就不一样了
但是 这个地方 * 单位的方式不是特别好些 所以我们这里搞了一个其他的东西
我们给它搞了一个静态方法来实现这个东西
import 'dart:ui';
class HYSizeFit {
static double physicalWidth;
static double physicalHeight;
static double screenWidth;
static double screenHeight;
static double dpr;
static double statusHeight;
static double rpx;
static void initialize() {
// 1. 手机的物理分辨率
physicalWidth = window.physicalSize.width; // 拿到物理的宽度
physicalHeight = window.physicalSize.height;
// 2. 求出dpr
dpr = window.devicePixelRatio;
// 3. 求出逻辑的宽高
screenWidth = physicalWidth / dpr;
screenHeight = physicalHeight /dpr;
// 4. 状态栏高度
statusHeight = window.padding.top / dpr;
// 5. 计算rpx
rpx = screenWidth / 750;
}
static double setRpx(double size) {
return size * rpx;
}
}
使用
class HYHomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("物理宽度高度 ${HYSizeFit.physicalWidth} * ${HYSizeFit.physicalHeight}");
return Scaffold(
appBar: AppBar(
title: Text("title")
),
body: Center(
child: Container(
width: HYSizeFit.setRpx(400),
height: HYSizeFit.setRpx(400),
color: Colors.red,
child: Center(
child: Text("hello world", style: TextStyle(fontSize: HYSizeFit.setRpx(40)))
),
)
),
);
}
}
但是如果我们这里还是使用这个rpx不是要翻倍吗 不是很好用 所以我们可以再搞一个单位
import 'dart:ui';
class HYSizeFit {
static double physicalWidth;
static double physicalHeight;
static double screenWidth;
static double screenHeight;
static double dpr;
static double statusHeight;
static double rpx;
static double px;
static void initialize() {
// 1. 手机的物理分辨率
physicalWidth = window.physicalSize.width; // 拿到物理的宽度
physicalHeight = window.physicalSize.height;
// 2. 求出dpr
dpr = window.devicePixelRatio;
// 3. 求出逻辑的宽高
screenWidth = physicalWidth / dpr;
screenHeight = physicalHeight /dpr;
// 4. 状态栏高度
statusHeight = window.padding.top / dpr;
// 5. 计算rpx
rpx = screenWidth / 750;
px = rpx * 2;
}
static double setRpx(double size) {
return size * rpx;
}
static double setPx(double size) {
return size * px;
}
}
这样如果ui给的是一个px 就用px 如果用的是一个rpx那就可以用 rpx
有些时候 公司不是以750 为设计稿 所以我们可以封装更加好一点
这里我们可以给这个initialize 传递一个参数 standardSize 还给他整了一个默认参数
import 'dart:ui';
class HYSizeFit {
static double physicalWidth;
static double physicalHeight;
static double screenWidth;
static double screenHeight;
static double dpr;
static double statusHeight;
static double rpx;
static double px;
static void initialize({standardSize = 750}) {
// 1. 手机的物理分辨率
physicalWidth = window.physicalSize.width; // 拿到物理的宽度
physicalHeight = window.physicalSize.height;
// 2. 求出dpr
dpr = window.devicePixelRatio;
// 3. 求出逻辑的宽高
screenWidth = physicalWidth / dpr;
screenHeight = physicalHeight /dpr;
// 4. 状态栏高度
statusHeight = window.padding.top / dpr;
// 5. 计算rpx
rpx = screenWidth / standardSize;
px = screenWidth / standardSize * 2;
}
static double setRpx(double size) {
return size * rpx;
}
static double setPx(double size) {
return size * px;
}
}
还有 一种方案是使用extension 用这个数值参数的 扩展类 然后将 这个写法继续优化
我们新建一个extensio int 这样就相当于在 int类中写东西
但是注意我们的dart是没有 隐式转换的
import "size_fit.dart";
extension IntFit on int {
double get px {
return HYSizeFit.setPx(this.toDouble());
}
double get rpx {
return HYSizeFit.setRpx(this.toDouble());
}
}
import 'package:learn_flutter02/day14_screenfit/shared/size_fit.dart';
extension DoubleFit on double {
// double px() {
// return HYSizeFit.setPx(this);
// }
//
// double rpx() {
// return HYSizeFit.setRpx(this);
// }
double get px {
return HYSizeFit.setPx(this);
}
double get rpx {
return HYSizeFit.setRpx(this);
}
}
我梦给他增加一个 方法 来获得对应的 rpx px值
导入对应的文件使用
import "package:flutter/material.dart";
import "shared/size_fit.dart";
import "extension/double_extension.dart";
import "extension/int_extension.dart";
main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 导入文件 然后初始化
HYSizeFit.initialize();
return MaterialApp(
title: "Flutter Demo",
theme: ThemeData(
primarySwatch: Colors.blue,
splashColor: Colors.transparent
),
home: HYHomeScreen(),
);
}
}
class HYHomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("物理宽度高度 ${HYSizeFit.physicalWidth} * ${HYSizeFit.physicalHeight}");
return Scaffold(
appBar: AppBar(
title: Text("title")
),
body: Center(
child: Container(
width: 400.rpx,
height: 200.px,
color: Colors.red,
child: Center(
child: Text("hello world", style: TextStyle(fontSize: 40.rpx))
),
)
),
);
}
}
这种方式更加简洁