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,
  );
}
相关推荐
zwjapple1 小时前
docker-compose一键部署全栈项目。springboot后端,react前端
前端·spring boot·docker
像风一样自由20203 小时前
HTML与JavaScript:构建动态交互式Web页面的基石
前端·javascript·html
aiprtem4 小时前
基于Flutter的web登录设计
前端·flutter
浪裡遊4 小时前
React Hooks全面解析:从基础到高级的实用指南
开发语言·前端·javascript·react.js·node.js·ecmascript·php
why技术4 小时前
Stack Overflow,轰然倒下!
前端·人工智能·后端
GISer_Jing4 小时前
0704-0706上海,又聚上了
前端·新浪微博
止观止4 小时前
深入探索 pnpm:高效磁盘利用与灵活的包管理解决方案
前端·pnpm·前端工程化·包管理器
whale fall4 小时前
npm install安装的node_modules是什么
前端·npm·node.js
烛阴4 小时前
简单入门Python装饰器
前端·python
袁煦丞5 小时前
数据库设计神器DrawDB:cpolar内网穿透实验室第595个成功挑战
前端·程序员·远程工作