Flutter中尺寸的单位
Flutter 尺寸单位采用的是 逻辑像素 ,类似于 iOS 中的 pt 、Android 中的 dp。
概念对比
分类 | 说明 |
---|---|
逻辑像素 | 也被称为"与设备或分辨率无关的像素"。 |
物理像素 | 也称"设备像素",是屏幕的基础单位,也是我们能看到的尺寸。 示例:iPhone 6 的屏幕宽度方向有 750 个像素点 ,高度方向有 1334 个像素点。 |
Flutter 使用逻辑像素作为布局单位。逻辑像素 = 物理像素 px / devicePixelRatio
在 Flutter 中,
devicePixelRatio
由ui.Window
类提供。
Window
是 Flutter Framework 连接宿主操作系统的接口,因此devicePixelRatio
属性是引擎层从原生平台获取的。
- 在 Android 中对应
density
- 在 iOS 中对应
[UIScreen mainScreen].scale
相同逻辑像素在不同分辨率手机上看到的物理像素不同,原因是每个设备可能都会有不同的 dpr(devicePixelRatio)。
一个简单的适配工具类
我们的核心目标是让设计稿里的"100 × 100"之类的尺寸,在各种尺寸、分辨率的设备上得到"视觉上占屏幕宽度(或高度)的相同比例" 。
核心思路
- 以设计稿宽度为基准,计算设备宽度的缩放比(
ratio
)。 - 所有 UI 尺寸乘以
ratio
后再绘制,实现跨分辨率"看起来一致"。 - 借助 Dart 扩展方法 (
extension
) 把xx.px
写法变成语法糖,降低适配成本。
dart
import 'package:flutter/cupertino.dart';
/// =======================
/// Int 类型扩展 ------ 语法糖
/// =======================
/// 让数值直接写成 `200.px` 即可自动适配
extension IntFix on int {
/// 示例:`200.px`
/// 将 int 转为 double 再送给 ScreenHelper 计算
double get px => ScreenHelper.getPx(toDouble());
}
/// =======================
/// double 类型扩展 ------ 语法糖
/// =======================
/// 让小数也能写成 `200.0.px`
extension DoubleFix on double {
/// 示例:`200.0.px`
double get px => ScreenHelper.getPx(this);
}
/// =======================================
/// ScreenHelper ------ 屏幕适配核心工具类
/// =======================================
class ScreenHelper {
/// 设备屏幕信息
static late MediaQueryData _mediaQueryData;
/// 设备屏幕宽高(逻辑像素)
static late double screenWith; // 当前设备宽度
static late double screenHeight; // 当前设备高度
/// 设计稿基准宽度与设备宽度的缩放比
static late double ratio;
/// ------------------------------------------------
/// 初始化:在 APP 启动的首个页面调用
/// 例如:ScreenHelper.init(context, baseWidth: 375);
///
/// @param context BuildContext,用于获取 MediaQuery
/// @param baseWidth UI 设计稿的宽度(假设默认 375)
/// ------------------------------------------------
static void init(BuildContext context, {double baseWidth = 375}) {
_mediaQueryData = MediaQuery.of(context);
screenWith = _mediaQueryData.size.width; // 设备实际宽度
screenHeight = _mediaQueryData.size.height; // 设备实际高度
// 计算缩放比:设备宽 ÷ 设计稿宽
ratio = screenWith / baseWidth;
}
/// ------------------------------------------------
/// 将"设计稿尺寸"转换为当前设备应显示的逻辑像素
///
/// 使用方式:`50.px` 或 `ScreenHelper.getPx(50)`
/// ------------------------------------------------
static double getPx(double size) => ratio * size;
}
使用示例
arduino
dart
@override
Widget build(BuildContext context) {
// 只需在应用入口或首个页面初始化一次
ScreenHelper.init(context, baseWidth: 375);
return Container(
width: 200.px, // 自动按比例适配
height: 200.px,
color: Colors.blue,
);
}