前移动端的设备已经非常多,并且不同的设备手机屏幕也不相同。
目前做移动端开发都要针对不同的设备进行一定的适配,无论是移动原生开发、小程序、H5页面。
Flutter中如何针对不同的手机屏幕来进行适配呢?我们一起来聊聊这个话题。
在进行Flutter开发时,我们通常不需要传入尺寸的单位,那么Flutter使用的是什么单位呢?
iPhone设备参数
在Flutter开发中,我们使用的是对应的逻辑分辨率
获取屏幕上的一些信息,可以通过MediaQuery:
// 1.媒体查询信息
final mediaQueryData=MediaQuery.of(context);
// 2.获取宽度和高度
final screenWidth=mediaQueryData.size.width;
final screenHeight=mediaQueryData.size.height;
final physicalWidth=window.physicalSize.width;
final physicalHeight=window.physicalSize.height;
final dpr=window.devicePixelRatio;
print("屏幕width:$screenWidth height:$screenHeight");
print("分辨率: $physicalWidth - $physicalHeight");
print("dpr: $dpr");
// 3.状态栏的高度
// 有刘海的屏幕:44 没有刘海的屏幕为20
final statusBarHeight=mediaQueryData.padding.top;
// 有刘海的屏幕:34 没有刘海的屏幕0
final bottomHeight=mediaQueryData.padding.bottom;
print("状态栏height: $statusBarHeight 底部高度:$bottomHeight");
获取一些设备相关的信息,可以使用官方提供的一个库:
dependencies:
device_info: ^0.4.2+1
二. 适配方案
假如我们有下面这样一段代码:
class HYHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("首页"),
),
body: Center(
child: Container(
width: 200,
height: 200,
color: Colors.red,
alignment: Alignment.center,
child: Text("Hello World", style: TextStyle(fontSize: 30, color: Colors.white),),
),
),
);
}
}
上面的代码在不同屏幕上会有不同的表现:
不同屏幕表现
在前端开发中,针对不同的屏幕常见的适配方案有下面几种:
这里我采用小程序的rpx来完成Flutter的适配
小程序中rpx的原理是什么呢?
rpx的对应关系
那么我们就可以通过上面的计算方式,算出一个rpx,再将自己的size和rpx单位相乘即可:
我们自己来封装一个工具类:
class HYSizeFit {
static MediaQueryData _mediaQueryData;
static double screenWidth;
static double screenHeight;
static double rpx;
static double px;
static void initialize(BuildContext context, {double standardWidth=750}) {
_mediaQueryData=MediaQuery.of(context);
screenWidth=_mediaQueryData.size.width;
screenHeight=_mediaQueryData.size.height;
rpx=screenWidth / standardWidth;
px=screenWidth / standardWidth * 2;
}
// 按照像素来设置
static double setPx(double size) {
return HYSizeFit.rpx * size * 2;
}
// 按照rxp来设置
static double setRpx(double size) {
return HYSizeFit.rpx * size;
}
}
初始化HYSizeFit类的属性:
class HYHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 初始化HYSizeFit
HYSizeFit.initialize(context);
return null;
}
}
使用rpx来完成屏幕适配:
class HYHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
HYSizeFit.initialize(context);
return Scaffold(
appBar: AppBar(
title: Text("首页"),
),
body: Center(
child: Container(
width: HYSizeFit.setPx(200),
height: HYSizeFit.setRpx(400),
color: Colors.red,
alignment: Alignment.center,
child: Text("Hello World", style: TextStyle(fontSize: HYSizeFit.setPx(30), color: Colors.white),),
),
),
);
}
}
我们来看一下实现效果:
rpx适配方案
屏幕适配也可以使用第三方库:flutter_screenutil
原文出处:https://mp.weixin.qq.com/s/z21YZ4FhSswpDWn4KpK6jw(侵权删除)
着网络与科技的快熟发展,越来越多的手机厂商开始打起手机之间的战争,手机的快速发展也使得越来越多的人开始使用手机上网。移动设备正超过桌面设备,成为访问互联网的最常见终端。那么就会出现一个问题,如何才能让PC端的网页在手机上正常显示?手机与PC的屏幕宽度有着很大的区别,会造成同样的内容在手机与PC端出现两种不同的显示结果。那该如何才能使得手机与PC都能对网页呈现出令人满意的结果呢,本文收集了以下几种方法,有兴趣的小伙伴们可以看下:
1、在网页代码的头部,加入一行viewport元标签。
viewport是网页默认的宽度和高度,上面这行代码的意思是,网页宽度默认等于屏幕宽度(width=device-width),原始缩放比例(initial-scale=1)为1.0,即网页初始大小占屏幕面积的100%。
注意:该方式不支持IE8及IE8以下的版本
2、不使用绝对宽度
由于网页会根据屏幕宽度调整布局,所以不能使用绝对宽度的布局,也不能使用具有绝对宽度的元素。对图像来说也是这样。
具体说,CSS代码不能指定像素宽度:width:xxx px;
只能指定百分比宽度: width: xx%; 或者 width:auto;
3、使用相对大小的字体
字体也不能使用绝对大小(px),只能使用相对大小(em或者rem)
例如: body
上面的代码指定,字体大小是页面默认大小的100%,即16像素(1em=16px)。
h1
h1的大小是默认大小的1.5倍,即24像素(24/16=1.5)
将想要的像素去除默认的16像素可以得到em
4、流动布局(fluid grid)
"流动布局"的含义是,各个区块的位置都是浮动的,不是固定不变的。
.main
.leftBar
float的好处是,如果宽度太小,放不下两个元素,后面的元素会自动滚动到前面元素的下方,不会在水平方向overflow(溢出),避免了水平滚动条的出现。
5、媒体查询器@media
"自适应网页设计"的核心,就是CSS3引入的MediaQuery模块。
它的意思就是,自动探测屏幕宽度,然后加载相应的CSS文件。
上面的代码意思是,如果屏幕宽度小于400像素(max-device-width: 400px),就加载tinyScreen.css文件。
如果屏幕宽度在400像素到600像素之间,则加载smallScreen.css文件。
辑导语:虽然国内软件的iPad用户占比不大,但依然存在着横屏适配的需求。本文作者讲述了自己做iPad横屏适配的背景,并对竞品的适配方式进行了分析研究,用自己的亲身经历提供了参考,推荐对ipad横屏适配感兴趣的童鞋阅读。
在我参与的一款资料查询 App 中,对 iPad 只支持竖屏以手机 UI 尺寸拉伸,每个季度都有用户反馈希望适配 iPad 横屏。经过询问用户发现,因为 iPad mini 尺寸刚好可以放在工作服口袋中,随时拿出来使用,而 iPad 屏幕远比手机大,浏览资料视野更大更舒服。
但另外一方面,后台数据显示当前 iPad 用户占比只有 1%,用户呼声够不上星星之火,不足以燎原。先别谈说服团队做 iPad 横屏适配,连说服自己都难。本来以为这事就像水中投石,水波消散就没有下文了。直到有一天,同样是资深用户的高管自己拿着 iPad 装上我们的 App 用了几天,终于忍不了,开始推动 iPad 横屏适配。
我们肯定不是第一个做 iPad 横屏适配的,但在网上搜了一圈,别说横屏适配,连 iPad 界面设计的文章都很少,下面 3 篇算不错的。这也是我决定写下本文的原因,为后来者提供经验,少踩坑。
没得经验参考就只能先从竞品分析开始了。经过对 iOS 系统应用、微信、QQ、微信阅读、得到、豆瓣、淘宝和有道词典的分析,我和同事总结成 5 种横屏适配模式。
典型 App:iOS 应用商店
特征:标题栏和 Tabbar 通栏拉伸,内容区根据宽度向右响应式布局。
适用场景:全部场景。
评价:灵活性和用户体验都很好,但设计和开发成本很大。
典型 App:iOS 设置、淘宝、微信、QQ
特征:左右分开显示,左边通常固定显示首页或者目录导航。右侧根据左侧选择显示对应的详情内容。
适用场景:频繁需要使用导航切换内容。
评价:用户体验适中,合理的利用横屏更大地展示更多的内容。设计成本小,需额外设计一个右侧默认为空的情况。开发成本要看是否改程序架构,相当于把手机两个手机界面合并成一个屏幕,可能有些程序架构很难这么修改。
典型 App:微信阅读
特征:标题栏和 Tabbar 通栏拉伸,内容直接按竖屏的宽度显示。
适用场景:全部场景。
评价:用户体验适中,设计与开发成本小,大多数产品采用此模式,但是没有更好的展现横屏宽屏的优势。
典型 App:豆瓣
特征:横屏为全屏通栏拉伸,所有元素与竖屏一致。
适用场景:全部场景。
评价:设计和开发成本最小,但是相当于没有适配。用户体验较差,横屏情况下内容集中,左侧右侧很空,或者被拉得很长,阅读体验较差。
当然也不是所有 App 都采用单一的模式。比如微信阅读,在其他页面是按竖屏宽度显示。但到了图书阅读界面,则是左右分栏充分利用 iPad 大屏幕展现内容。
以上竞品分析所有截图我们都保存在 Figma 中,有需要的读者可前往获取。
链接:https://www.figma.com/community/file/1071850659054902697/iPad-横屏适配竞品分析
非常遗憾的是虽然高管牵头做适配,但开发资源确实有限。不能为了设计师邀功拿业绩就从头把 iOS App 重构一遍,因此我们决定用最少的资源做最核心的优化。
适配计划分为 2 期。第 1 期将所有页面用按竖屏宽度显示进行横屏适配。第 2 期挑选核心页面用内容响应式或左右分栏进行优化。
在第 1 期我们就踩坑了,按照原来的工作流程,我们将所有的 iPad 横屏页面做好线框图、再输出所有视觉效果图。虽然都是线上页面不用重新设计,只需要拉伸画面或者调整间距,但所有线上页面也是一个不小的工作量。
就在进行过程中,iOS 工程师就皱着眉头来提议,由于代码架构和资源所限,设计师如果调整的视觉效果图未必能 100% 实现。不如反过来,让他先把所有页面强行横屏,再由设计师走查发现问题进行修改,这样节省时间效果也可控。
可见,不同的项目类型可以采取不同的工作流程。iPad 横屏适配项目流程和常规工作流程刚好相反,以往是先设计再开发,改成先开发再走查,节省设计师产出效果图时间,也保障最终实现效果。
在第 2 期挑选核心页面时,我也犯了错误。最开始我觉得核心是脸面,因此挑选 Tabbar 导航的首页、个人中心等用户一打开 App 就看得到的页面进行优化。但实际上用户真正的核心使用场景是在详情页查阅资料,这才是真正的核心页面。
在得到主管纠正后,我们转而开始为资料阅读页面提供左内容右目录的布局,便于用户方便地在长文中精确定位想读的内容。
2 期计划并非适配的终结,随着 App 功能的迭代,此后老界面修改和新界面设计需要考虑到 iPad 横屏的适配问题,就成为了日常工作的内容了。
按照以往的项目总结,最后应该汇报项目数据结果。但由于 iPad 用户本身可怜的占比,即使我们官方公众号推文宣布适配 iPad 横屏后,也没有 iPad 用户站出来点赞,而是又引发出使用华为、小米等安卓 Pad 的用户,要求也适配。
考虑到不同的安卓品牌适配方式不一样,而且安卓厂商自己又有平行世界等通用兼容方案,我们就没再继续参与了。
虽然没有外部用户反馈,但公司内部同事和开发团队使用后确实感觉很棒。所以我觉得这次适配项目真正值得思考的是:如果一个需求用户反馈很少,也没有数据支撑,但对体验影响很大,如何推动团队进行优化呢?
作者:龙爪槐守望者,微信公众号:龙爪槐守望者
本文由 @龙爪槐守望者 原创发布于人人都是产品经理。未经许可,禁止转载。
题图来自 Unsplash,基于 CC0 协议
*请认真填写需求信息,我们会在24小时内与您取得联系。