Flutter屏幕适配指南

Flutter中尺寸的单位

Flutter 尺寸单位采用的是 逻辑像素 ,类似于 iOS 中的 pt 、Android 中的 dp

概念对比

分类 说明
逻辑像素 也被称为"与设备或分辨率无关的像素"。
物理像素 也称"设备像素",是屏幕的基础单位,也是我们能看到的尺寸。 示例:iPhone 6 的屏幕宽度方向有 750 个像素点 ,高度方向有 1334 个像素点

Flutter 使用逻辑像素作为布局单位。逻辑像素 = 物理像素 px / devicePixelRatio

在 Flutter 中,devicePixelRatioui.Window 类提供。
Window 是 Flutter Framework 连接宿主操作系统的接口,因此 devicePixelRatio 属性是引擎层从原生平台获取的。

  • Android 中对应 density
  • iOS 中对应 [UIScreen mainScreen].scale

相同逻辑像素在不同分辨率手机上看到的物理像素不同,原因是每个设备可能都会有不同的 dpr(devicePixelRatio)。

一个简单的适配工具类

我们的核心目标是让设计稿里的"100 × 100"之类的尺寸,在各种尺寸、分辨率的设备上得到"视觉上占屏幕宽度(或高度)的相同比例"

核心思路

  1. 以设计稿宽度为基准,计算设备宽度的缩放比(ratio)。
  2. 所有 UI 尺寸乘以 ratio 后再绘制,实现跨分辨率"看起来一致"。
  3. 借助 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,
  );
}
相关推荐
独立开阀者_FwtCoder6 分钟前
从卡顿到丝滑,AI 应用体验跃升的幕后推手是它!
前端·vue.js·面试
知否技术10 分钟前
2025微信小程序开发实战教程(二)
前端·微信小程序
前端小巷子13 分钟前
跨标签页通信(一):BroadcastChannel
前端·面试·浏览器
前端付豪14 分钟前
微信支付风控系统揭秘:交易评分、实时拦截与行为建模全流程实战
前端·后端·架构
我有CV两法可开前端一片天16 分钟前
uni-app实现文件上传、下载、预览(非只图片和视频)
前端
断竿散人18 分钟前
CSS布局完全指南(下)-Flexbox完全征服指南:一维布局的终极解决方案
前端·css
前端付豪19 分钟前
微信视频号推荐系统揭秘:兴趣建模、多模态分析与亿级流控架构实战
前端·后端·算法
Aisanyi19 分钟前
【鸿蒙开发】PC实现开局沉浸式全屏
前端·华为·harmonyos
umigreen20 分钟前
Hbuildx运行app在模拟器
前端·app
自学前端_又又21 分钟前
3年Vue3,借Trae之力,实现转React的有缝连接
前端·javascript·trae