Flutter屏幕适配指南

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"之类的尺寸,在各种尺寸、分辨率的设备上得到"视觉上占屏幕宽度(或高度)的相同比例" 。

核心思路

  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,
  );
}
相关推荐
开开心心就好几秒前
视频模糊怎么修复?免费工具支持批量处理
java·前端·人工智能·智能手机·pdf·excel
变与不变8061 分钟前
jspost请求详解
前端·javascript
派小心.36 分钟前
React StrictMode埋点双执行的验收方法
前端·前端框架
IT_陈寒44 分钟前
Python的GIL锁让我把多线程代码全重写了!
前端·人工智能·后端
百度一下吧1 小时前
umi后台管理项目实战:从工程搭建到生产构建
java·前端·javascript
派小心.1 小时前
App埋点排查:iOS冷启动事件漏报先看初始化还是上报
前端·数据分析
事圆则缓1 小时前
Flutter 状态管理框架对比(六):同一个购物车,四种方案怎么落地?
前端·javascript·flutter
peter67681 小时前
css揭秘-背景和边框
前端·css
派小心.1 小时前
小程序埋点验收:自定义事件上报后页面参数怎么核对
前端·数据分析
前端snow11 小时前
ai agent --- postgreSQL 关系型数据库
前端