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,
  );
}
相关推荐
mldong3 小时前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排4 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60614 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角5 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!5 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰6 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
mayaairi7 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen8 小时前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能
风骏时光牛马8 小时前
AI源码分析:拆解模型底层实现逻辑
前端
IT_陈寒9 小时前
React子组件莫名其妙重渲染?你可能漏了这个Hook
前端·人工智能·后端