【Flutter 问题系列第 73 篇】如何在 Flutter 应用中进行屏幕适配(含使用教程、原理解析)

这是【Flutter 问题系列第 73 篇】,如果觉得有用的话,欢迎关注专栏。

一:问题描述

随着移动端的设备越来越多样化,尤其是安卓手机五花八门的屏,屏幕适配也变得越来越复杂。

那么在 Flutter 中针对不同分辨率的手机如何进行屏幕适配呢?

前面先说下如何屏幕适配,省去那些繁文缛节,怎么简单怎么来,如果有用,可以再来看末尾的解析。

二:解决方案

这里用到 pub 上的第三方插件库 flutter_screenutil,截止到发文插件已经更新到了 5.5.3+2。

因为我一直用的是 5.0.0+2 版本,挺稳定的,所以后面将以 5.0.0+2 版本为例说明 flutter_screenutil 插件如何使用。

2-1:引入、获取依赖

在项目的配置文件 pubspec.yaml 中引入依赖,如下图所示

在这里插入图片描述

然后在终端执行 flutter pub get 命令获取依赖。

2-2:初始化插件

为方便后续使用,我们定义一个 util 的文件夹,新建一个 rpx.dart 文件,然后在此文件中进行插件的初始化。

代码如下所示

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';

// ------------------------------------------------------
// author:Allen Su
// date  :2022/7/7 23:04 
// usage :屏幕适配
// ------------------------------------------------------

/// 初始化屏幕适配(以 iphone6 为设计尺寸)
void initScreenUtil(BoxConstraints constraints) {
    
    
  ScreenUtil.init(constraints, designSize: Size(375, 667));
}


/// rpx 根据屏幕宽度自适应 1rpx = 0.5px = 1物理像素
double rpx(double rpx) {
    
    
  return ScreenUtil().setWidth(rpx);
}

这里将 rpx 设备为全局的方便调用(之前用的静态类,每次使用起来很麻烦)

注:至于为什么命名为 rpx 和为什么要以 375x667 为设计尺寸,放在文末进行解释说明。

初始化插件的方法有了,在哪里调用呢?需要在 main.dart 中,并且在加载 MaterialApp 之前进行初始化

代码如下所示

class AllenSuApp extends StatelessWidget {
    
    
  @override
  Widget build(BuildContext context) {
    
    
    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraints) {
    
    
        initScreenUtil(constraints); // 初始化屏幕适配插件
        return MaterialApp(
          home: HomePage(),
        );
      },
    );
  }
}

准备工作已经完成,接下来就是如何使用了。

2-3:如何使用插件

使用起来非常的简单,只需要把要设置的数字直接当作参数传给 rpx 即可,比如设计稿给的盒子宽是 150 ,那你就直接把 150 填进去即可。

下面举例说明。

例一:设置字体大小

  Widget _view() {
    
    
    return Text(
      "大家好,我是 Allen Su",
      style: TextStyle(fontSize: rpx(16)),
    );
  }

例二:设置盒子大小

  Widget _view() {
    
    
    return Container(
      width: rpx(150),
      height: rpx(100),
      padding: EdgeInsets.symmetric(vertical: rpx(15)),
      margin: EdgeInsets.symmetric(horizontal: rpx(10)),
    );
  }

其它的情况大家举一反三即可,使用起来是不是特别的方便呢?

5.5.3+2 版本的改动和适配

我也下载了 5.5.3+2 版本的插件,相比较当前代码,只是在初始化插件时,把参数类型由 BoxConstraints 改为了 BuildContext,修改后的代码如下所示

void initScreenUtil(BuildContext context) {
    
    
  ScreenUtil.init(context, designSize: Size(375, 667));
}

相应地,在引用 initScreenUtil 的地方也要修改其参数类型。

现在你已经会在 Flutter 应用中进行屏幕适配了,如果你对其原理有兴趣可以继续往下看。

三:屏幕适配原理及 rpx 的解释说明

①:原理

查看 flutter_screenutil 插件的源码可知,针对不同设备只是把原型图上的尺寸等比例放大和缩小了,其原理是

开发尺寸 / 原型图尺寸 = 实际屏幕宽度 / 原型图屏幕宽度

②:什么是 rpx

rpx 单位是微信小程序中 css 的尺寸单位,rpx 可以根据屏幕宽度进行自适应,规定屏幕宽为750rpx,

具体的可以点击查看微信小程序中对于 rpx 的解释说明。

③:Flutter 中的单位

我们知道在 Android 中常用的单位有 px、dp、sp 等,在 iOS 中是以 pt(point)为单位,在 Flutter 中的单位是什么呢?

Flutter 的单位使用的类似于 iOS 中的 pt,像我们平常所说的 iphone6 的尺寸是 375x667,但其实它的分辨率是 750x1334。

④:rpx 和 px 的换算关系

也就是说,rpx 和 px 存在这样的关系

  • 1 rpx = 0.5 px = 1 物理像素
  • 1 px = 1 物理像素 = 2 rpx

这也是为什么我们会以 375x667 作为初始尺寸。而不是 750x1334。

⑤:为什么使用 rpx 不需要进行单位转换

这里放一张截图,看下其它设备的换算关系

在这里插入图片描述

因为设计图一般为 2 倍图,所以我们可以直接 rpx 单位,不用再进行二次转换了。

目前为止并没有完美的屏幕适配方案,我们只能尽可能的做到完美,所以这需要我们平常多多注意可能溢出、布局错乱的问题(Flutter 也提供了自适应的组件如 SafeArea、Expanded 等)

这也是为什么我们可以直接把原型图中的尺寸,当作参数写入到封装好的 rpx 方法中的原因。

不知不觉已经 1点 22 了,本来想着两个小时可以写完的,溜了溜了~

至此,如何在 Flutter 应用中进行屏幕适配便介绍到这里。

你的问题得到解决了吗?欢迎在评论区留言。

赠人玫瑰,手有余香,如果觉得文章不错,希望可以给个一键三连,感谢。


结束语

Google 的 Flutter 越来越火,截止 2022年7月8日 GitHub 标星已达 142K,Flutter 毅然是一种趋势,所以作为前端开发者,没有理由不趁早去学习。

无论你是 Flutter 新手还是已经入门了,不妨先点个关注,后续我会将 Flutter 中的常用组件(含有源码分析、组件的用法及注意事项)以及可能遇到的问题写到 CSDN 博客中,希望自己学习的同时,也可以帮助更多的人。

猜你喜欢

转载自blog.csdn.net/qq_42351033/article/details/125668547