flutter 屏幕适配
本文最后更新于:2022年4月22日 上午
flutter 屏幕适配
屏幕适配
flutter
中编写的像素单位是固定的,如果要做在不同设备上的屏幕适配,需要开发者手动适配(类似小程序中的 rpx
适配,会将手机屏幕以750
宽度作为基准,开发者通过做好该宽度的适配即可在不同屏幕上自动拥有不同的大小效果)
适配方式
- 通过设备的 物理宽高 除以
dpr
得到逻辑宽高
逻辑宽高
除以设计稿宽度
(一般以6/6s
的750
做基准) 得到dpr
- 设置像素的时候通过 像素 乘以
dpr
得到 可以自适应的宽高
例如 设备逻辑宽度是 750
,dpr
是2
,那么得到逻辑宽是 750/2 = 375
,那么就会把 375
当做设备的宽度。
再用 逻辑宽度 / 设计稿宽度 得到 rpx 375/750 = 0.5
设置像素的时候 都用 像素 乘以 刚刚算出的 rpx
,如 100 * 0.5 = 50
,那么这个像素在当前设备上就是 50
假如换到 iphone xr
上rpx
就是 414/750 = 0.552
,再用像素乘以rpx 100*0.552 = 55.2
,那么在 xr 上就是宽度就是 55.2
封装获取 rpx
class HotSize {
static double standardSize = 750; // 设计稿尺寸
static double physicalWidth = 0; // 物理宽度
static double physicalHeight = 0; // 物理高度
static double dpr = 2; // 缩放比例
static double width = 0; // 逻辑宽度
static double height = 0; // 逻辑高度
static double tabHeight = 0; // 头部状态栏高度
static double rpx = 0; // rpx
static double px = 0; // px
static init() {
// 获取物理宽高
physicalWidth = window.physicalGeometry.width;
physicalHeight = window.physicalGeometry.height;
// 获取 dpr
dpr = window.devicePixelRatio;
// 计算逻辑宽高
width = physicalWidth / dpr;
height = physicalHeight / dpr;
tabHeight = window.padding.top;
rpx = width / standardSize;
px = width / standardSize * 2;
}
// 设置 rpx
double setRpx(double size) => size * rpx;
double setRx(double size) => size * px;
}
使用
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('屏幕')),
body: Center(
child: Container(
width: HotSize().setRpx(750),
height: HotSize().setRpx(300),
color: Colors.green,
),
),
// body: Text('home'),
);
}
}
优化写法
上述写法每次都需要调用 setRpx()
来设置 rpx
,会较为繁琐,我们可以通过扩展的方式来简化写法
import '../utils/hot_size.dart';
// 扩展 int
extension intHotSize on int {
double get rpx => HotSize.setRpx(this.toDouble());
double get px => HotSize.setPx(this.toDouble());
}
import '../utils/hot_size.dart';
// 扩展 double
extension doubleHotSize on double {
double get rpx => HotSize.setRpx(this.toDouble());
double get px => HotSize.setPx(this.toDouble());
}
使用
需要先进行导入
import 'package:learn_fluuter_00/cookbook/extensions/int.dart';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('美食广场')),
body: Container(width: 200https://api.flutter-io.cn/flutter/static-assets/favicon.png?v1.rpx, child: Text('首页')),
);
}
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议,转载请注明出处。