flutter-UI百分比适配
基础知识与适配方案
flutter
屏幕适配过程中难免会碰到尺寸问题,也就是说不是设计给多少就能写多少的,flutter
默认的尺寸为:dp(android)
、pt(ios)
,可以理解为1倍像素下的标准尺寸,具体表现为 像素/倍率(1、2、3)
我们开发过程中,以蓝湖为例,设计一般会以 375
或 750
屏幕宽为模板进行开发,实际上就是以 iphone6
为标准开发,分别表示的是 pt
和 px
,iphone6
2倍像素屏,所以屏幕基本宽度 375
, 宽度占用像素为 750
,到这里相信都理解了这两者的关系
目前主流适配方案大致有两种
(都是以宽度为参考):
- 按照设计稿等比适配
- 间距固定,内容根据剩余宽度等比放大或者缩小(毕竟横向也放不了多少东西)
dp、pt适配方案(间距固定、内容填充适配)
:
这种方案一般都是使用 dp、pt
方案来适配的,一般适用于横向内容比较少的页面,一般应用在带图片的内容浏览,越是大屏,内容区域会越大,观看体验越佳,这也是以前比较主流的适配方案,现在也同样适用,相比与下面的百分比,有时候有些布局需要略微多动一点脑子罢了(而不是特殊布局直接按宽为750
来布局),不过没事僵尸还没吃掉我的脑子,还勉强够用😂
百分比适配方案
根据设计稿宽度,等比例适配到真机上,两者只需要相除便可以得出比例,适用设计稿像素*基本百分比
即可,这样可以保证宽度上在不同宽度的手机上表现得大致相同(会有一个像素左右误差,毕竟像素不会出现0.1、0.9之类的)
这也是目前跨平台应用普遍采用的适配方案(既然跨平台了,那么都一样吧😂)
混合适配
混合适配就是根据内容和平台的展示,选择使用百分比
还是dp、pt方案
例如根据内容分割:朋友圈分享页面选择dp、pt方案
,购物导航页选择百分比
实际上一般应用都只会使用 百分比
方案适配更加方便,如果想在大屏平台上让体验更佳一些,且同时应用到 ipad
上面的应用较多采用 dp、pt方案
,而仅仅手机端则采用 百分比
的更多一点
百分比适配方案代码准备
以 dart 为例(可转化为适合自己的编程语言),生成下面代码,以便使用
import 'dart:ui';
import 'package:flutter/material.dart';
class AdaptUtil {
//设备基本信息对象
static final MediaQueryData mediaQuery = MediaQueryData.fromWindow(window);
//屏幕宽度dp
static final double width = mediaQuery.size.width;
//屏幕高度dp
static final double height = mediaQuery.size.height;
//屏幕像素倍率
static final double ratio = mediaQuery.devicePixelRatio;
static final double dp2pxRatio = width / 750;
//传入设计稿 750 像素宽度为参考的尺寸 dp2px
static double dp2px(double dp2px) {
return dp2px * dp2pxRatio;
}
//传入px转化成dp
static double px(double px) {
return px / ratio;
}
}
由于都是静态方法,直接通过类名调用即可
//根据750像素宽的设计稿,传入尺寸
Container(
width: AdaptUtil.dp2px(750),
),
//必要时传入像素
Container(
width: AdaptUtil.px(120),
),
应用到flutter的案例改进
实际使用过程中,由于数字都是num
对象,因此可以直接对num
进行扩展即可,给转化逻辑包装成属性的样子,方便调用
import 'dart:ui';
import 'package:flutter/material.dart';
final MediaQueryData mediaQuery = MediaQueryData.fromWindow(window);
//屏幕像素倍率
final double ratio = mediaQuery.devicePixelRatio;
//屏幕宽度dp
final double width = mediaQuery.size.width;
//屏幕高度dp
final double height = mediaQuery.size.height;
final double dp2pxRatio = width / 750;
//方便外边调用,不用模块化导出了,打出类名就能拿出变量了
class AdaptUtil {
//屏幕宽度dp
static final double width = width;
//屏幕高度dp
static final double height = height;
//padding,例如:x 以及以上底部是 34 (.bottom),使用其可以避免底部按钮点不到的问题
static final EdgeInsets padding = mediaQuery.padding;
}
//为了方便使用,我们伪装成属性调用(实际应该是伪属性,不存在该字段)
extension Adapt on num {
//使用扩展方便调用,以边距750为例
double get sp => this * dp2pxRatio;
//将dp、pt转化为px
double get px => this / ratio;
}
调用的时候只需要.sp即可
//如下所示调用即可,由于直接调用了方法, 因此不能使用 const,需要注意了
width: 10.sp
最后
你可能会觉得,百分比适配过程中每个都要走转化的方法,那么性能不就变低了么?
这是肯定会有一点影响的,但这类纯计算的一般影响不大,优先从别的地方进行性能优化,如果该优化的都优化了还是存在性能问题,那么要不就放弃跨平台使用原生,要不就产品选择更新内容来进行优化(不过只要功能合理一般应当以产品为主,毕竟产品竞争力很关键,他们负责将产品设计好,我们负责将技术瓶颈解决,以提升项目整体竞争力,毕竟合作共赢)
PS
: 实在搞不定的实现和优化点,找产品砍需求,有时间条件的可以纳入原生尝试混编开发😂,当然如果你觉得百分比的这个拖累了速度,可以仅仅采用 dp、pt适配方案
,也是完全ok,不过这种方案有时需要自己额外估算间距
转载自:https://juejin.cn/post/7145442432698712101