如何适配不同分辨率和不同屏幕尺寸的手机

如何适配不同分辨率和不同屏幕尺寸的手机,第1张

Android应用如何适配不同分辨率的手机,主要分三块考虑:
1界面配置,根据不同的分辨率,创建手机界面文件
例子:
在res下创建 layout-800x480,layout-480x320,并在各自不同分辨率的文件夹下创建界面文件
2配置,不同的分辨率,界面的长宽比不一致,需要不同规格的,在drawable-hdpi,drawable-ldpi,drawable-mdpi 中放不同分辨率的
注:为了减小整个应用程序安装包大小,选用最高分辨率适配,特殊界面特殊处理
3动态实现的界面,样式的设定,不同分辨率,界面的字体大小,字体等需要不同的样式,且需要动态生成的情况下,需要把不同分辨率的配置信息保存到应用中。
例子:
在RES里创建 values-480x320 values-800x400 value-1280x720,并在创建的文件夹中分别创建dimensxml,<dimen name="Text_size">30px</dimen>,在程序中直接调RdimenText_sizeint sizeOfText = (int) thisgetResources()getDimension(RdimenText_size);
注:实际应用发现,字体大小适配时,比如只适配了如下屏幕字体
values-480x320 values-800x480 value-1280x720当出现手机屏幕分辨率为 854x480时会自动找最大字体适配 (value-1280x720)
总结:如果字体800x480以上没有适配,手机自动按最大分辨率适配

1 MagicNumber -> autoresizingMask -> autolayout
以上是纯手写代码所经历的关于页面布局的三个时期
在iphone1-iphone3gs时代 window的size固定为(320,480) 我们只需要简单计算一下相对位置就好了
在iphone4-iphone4s时代 苹果推出了retina屏 但是给了码农们非常大的福利:window的size不变
在iphone5-iphone5s时代 window的size变了(320,568) 这时autoresizingMask派上了用场(为啥这时候不用Autolayout 因为还要支持ios5呗) 简单的适配一下即可
在iphone6+时代 window的width也发生了变化(相对5和5s的屏幕比例没有变化) 终于是时候抛弃autoresizingMask改用autolayout了(不用支持ios5了 相对于屏幕适配的多样性来说autoresizingMask也已经过时了)
那如何快速的上手autolayout呢 说实话 当年ios6推出的同时新增了autolayout的特性 我看了一下官方文档和demo 就立马抛弃到一边了 因为实在过于的繁琐和啰嗦(有过经验的朋友肯定有同感)
直到iphone6发布之后 我知道使用autolayout势在必行了 这时想起了以前在浏览Github看到过的一个第三方库Masonry 在花了几个小时的研究使用后 我就将autolayout掌握了(重点是我并没有学习任何的官方文档或者其他的关于autolayout的知识) 这就是我为什么要写下这篇文章来推荐它的原因
介绍
Masonry 源码
Masonry是一个轻量级的布局框架 拥有自己的描述语法 采用更优雅的链式语法封装自动布局 简洁明了 并具有高可读性而且同时支持 iOS 和 Max OS X
我们先来看一段官方的sample code来认识一下Masonry
1 [view1 mas_makeConstraints:^(MASConstraintMaker make) { 2makeedgesequalTo(superview)withinsets(padding); 3 }];
看到block里面的那句话: make edges equalTo superview with insets
通过链式的自然语言 就把view1给autolayout好了 是不是简单易懂
使用

这里用 iPhone 6举例子是因为大部分设计师都用 iPhone 6 来做设计稿,方便大家理解,其实 iPhone 8也是这个分辨率。iPhone 6:750×1334(375x667pt @2x)

iPhone X :1125px × 2436px (375pt × 812pt @3x)在逻辑像素上 iPhone X 的宽度和 iPhone 6 保持一致,这是高度高了145pt(812-667),如果你是用@1x做设计稿的时候,那么你在适配 iPhone X 的时候会方便很多很多,因为只需要增加高度就能得到 iPhone X 的大小,你所有的 symbol 基本都不要变,只是复制几个苹果爸爸的 symbol 到你 symbol 里面即可。用来做 iPhone X 的设计稿(一般也不单独做 iPhone X 设计)但是如果你用@2x 来做设计稿的只是稍微麻烦点,毕竟苹果爸爸Sketch UI Kit 都是基于@1x 来做设计稿的,所以你只能把 symbol 重新解散然后做成@2x大小的尺寸,会比较麻烦。

虽然它们的逻辑像素宽度一致,但是他们的像素分辨率是不一样的,iPhone 6 采用@2x切图,iPhone X 采用@3x 切图。有人会有用@2x 做设计稿那怎么适配 iPhone X 设计稿,难道要缩放?? iPhone 6 (750x1334px)尺寸到 iPhone X(1125x2436px),虽然两者的宽度关系是15倍,但是通过缩放做 iPhone X 也是相当麻烦啊,因为你的 Sketch 设计稿里面可能存在 symbol,所以这样的做法是行不通的,其实如果你的团队都是用@2x 来做设计稿的话,也没啥问题,那接下来的就提供一个更简单的方法解决 iPhone X 适配问题。

iPhone X 适配,我列出了 iPhone X 的三种分辨率的尺寸:375x812pt(@1x),750x1624px(@2x),1125×2436(@3x)

如果你使用的是750×1334(@2x)的设计稿,你在适配 iPhone X 的时候可以采用 iPhone X_@2x的图来适配,这样就省去了缩放这一步骤,而且开发使用的是逻辑像素即375pt × 812pt来做 iPhone X 的设计还原的,所以你这样设计 iPhone X 是不会影响开发的,因为750x1624px(@2x)还原到@1x 还是375x812pt,相信你已经明白了。

iPhone X安全区域问题

如果你用@1x 来做设计稿:iPhone X 安全区域是375x734pt

如果你用@2x 来做设计稿:iPhone X 安全区域是750x1468px

如何计算 iPhone X 安全区域

@1x 的 iPhone X 安全区域:其实安全区域=812pt—Status Bar (44pt) Home Indicator(34pt)

@2x 的 iPhone X 安全区域:其实安全区域=1624px—Status Bar (88px) Home Indicator(68px)

iPhone X 实际案例适配

在开始之前,我们先看一下其他 app 怎么适配之前的 iOS 设备的,我们可以知道头部区域采用了等比例的方法来适配,因为只有这样才能保证640×1136上面能够放得下相应的内容。其他的只需要放置相应的切图即可。

一开始以为头部适配很简单就没有特别在意,我们一开始也采用了等比例适配,后来发现没有必要,因为 640×1136 上基本可以显示完全。然后我们就开始适配 iPhone X 了,后来开发通过 Xcode 模拟出 iPhone X 的适配结果,我发现问题好像出现了,所以我陷入了沉思。是不是我方法不对?后来跟我们的用药助手 iOS 开发讨论了以后,发现原来导航栏的高度不是简单的200pt 解决的,这里我们采用的是固定高度的做法而不是采用等比例的做法,一般这块区域可以有2种做法:等比例和固定高度,看你页面的构成,如果页面内容较少可以采用固定高度的做法。不然的话可能在小屏幕手机有些内容放不下。

在没有 iPhone X 之前,固定高度做法:可以直接整体蓝色区域高度给200pt 解决问题,不用考虑导航栏问题~

但是 iPhone X 出来了,这样的做法就会行不通,因为 iPhone X 的导航栏高度是44pt 44pt=88pt,比 iPhone 6的导航栏(64pt)高了24pt,所以正确适配 iPhone X 的做法应该是导航栏区域高度(88pt) (200pt-64pt)=224pt,相信大家也知道了其实说白了就是 Status Bar 高度多了24pt,所以224pt 比200pt 大了24pt。

最后总结

这里只是讲解了iPhone X 一小部分和 iOS 适配问题,还有其他适配的经验希望大家在工作中去积累总结,我这里就不一一讲解了。

由于 iPhone X的屏幕比例发生变化,对于长期靠“等比缩放”完成适配的H5活动页而言也有不小的影响,需要对页面结构进行适当微调(注意缩放的时候不要把主体裁切了,然后注意页面的布局在 iPhone X 上面的变化)

如果你的 app 有全屏尺寸的活动图,没有导航栏,这个时候应该给开发 @2x(750×1334) 和 @3x(1125×2001) 图,然后 iPhone X 上的图会使用@3x的图按照高度铺满然后裁切两边(注意两侧被裁切区域不要包含重要内容)

在CSS中我们一般使用px作为单位,需要注意的是,CSS样式里面的px和物理像素并不是相等的。CSS中的像素只是一个抽象的单位,在不同的设备或不同的环境中,CSS中的1px所代表的物理像素是不同的。在PC端,CSS的1px一般对应着电脑屏幕的1个物理像素,但在移动端,CSS的1px等于几个物理像素是和屏幕像素密度有关的。

首先:我们必须了解几个概念,就是:Retina屏、物理像素、设备独立像素、设备像素比

所谓“Retina”是一种显示标准,是把更多的像素点压缩至一块屏幕里,从而达到更高的分辨率并提高屏幕显示的细腻程度。由摩托罗拉公司研发。最初该技术是用于Moto Aura上。这种分辨率在正常观看距离下足以使人肉眼无法分辨其中的单独像素。也被称为视网膜显示屏。Retina屏一般在苹果公司的产品上用的比较多,诸如MacBook、iPad、iPhone等

物理像素又被称为设备像素、设备物理像素,它是显示器(电脑、手机屏幕)最小的物理显示单位,每个物理像素由颜色值和亮度值组成。所谓的一倍屏、二倍屏(Retina)、三倍屏,指的是设备以多少物理像素来显示一个CSS像素,也就是说,多倍屏以更多更精细的物理像素点来显示一个CSS像素点,在普通屏幕下1个CSS像素对应1个物理像素,而在二倍Retina屏幕下,1个CSS像素对应的却是4个物理像素

设备独立像素是我们写CSS时所用的像素,它是一个抽像的单位,主要使用在浏览器上,用来精确度量Web页面上的内容。

设备像素比简称为dpr,物理像素与设备独立像素的比例。

当这个比率为1:1时,使用1个设备像素显示1个css像素。当这个比率为2:1=2时,使用4(2 2)个设备像素显示1个css像素。当这个比率为3:1=3,使用9(3 3)个设备像素显示1个css像素。
这里要注意,dpr=2,并不是物理像素是设备独立像素的2倍,而是用4个物理像素去表示1个设备逻辑像素

应该说1个设备独立像素是1个物理像素的4倍!!!!!,因为你4个网物理像素才代表我1个设备独立像素

dpr只代表一个数字比例,不是倍数关系。

CSS的1px等于几个物理像素,除了和屏幕像素密度dpr有关,还和用户缩放有关系。例如,当用户把页面放大一倍,那么CSS中1px所代表的物理像素也会增加一倍;反之把页面缩小一倍,CSS中1px所代表的物理像素也会减少一倍。关于这点,以后的1px细线问题部分还会讲到。

对于只需要适配少部分手机设备,且分辨率对页面影响不大的,使用px即可 。

对于需要适配各种移动设备,使用rem,例如只需要适配iPhone和iPad等分辨率差别比较挺大的设备。

rem是相对于根元素的字体大小的单位,也就是html的font-size大小,浏览器默认的字体大小是16px,所以默认的1rem=16px,我们可以根据设备宽度动态设置根元素的font-size,使得以rem为单位的元素在不同终端上以相对一致的视觉效果呈现。

事实上 rem是把屏幕等分成 指定的份数,以20份为例,每份为 1rem , 1rem 对应的大小就是 rem基准值 ,rem做的就是把 rem基准值 给<html>的 font-size ,所以如果设备的 物理像素 宽为 640px ,分成20份,那么 1rem=640px/20=32px , <html>的 font-size为32px 。

当然,你也可以分成30份,40份,60份等等,这个看自己的喜好了

在我们实际切图的时候,对于视觉稿上的元素尺寸换算,只需要元素的 原始的px值(即你量的大小) 除以 rem基准值 即可。例如设计稿的大小为640px, rem基准值 = 640px/20 = 32px ,有个元素的大小你量出来是 140px286px ,那么换算过来就是:

这样我们就可以用rem来代替像素px了, 而且在所有的移动端都是自适应的

这个方法目前是比较好的适配方法,只是rem在计算时很麻烦,有很多小数,这个时候大家可以试一下用less解决rem的小数问题

Android项目的res目录下一般加上我们自己创建的,会有6个目录,分别是:drawble drawble-ldpi drawble-mdpi drawble-hdpi drawble-xhdpi drawble-xxhdpi, 这里就不包括更为特殊的drawble目录了,(比如drawlbe-land-hdpi, 表示水平方向的高分辨率的,这些都目录不管多么长,它们都是按一丁点规律匹配的, 我们的目的是, 从个别中发现规律,从而应用到整体)。
当一个apk运行起来时,Android系统会根据其所运行的手机的屏幕密度去相对应的文件夹里找指定名称的。 注意, 先去哪个目录里找,完全是根据这个手机的屏幕密度决定的。
其中注意两点:
1, 中等分辨率,即mdpi的屏幕密度是160,他是标准的参考密度。所以计算比例的时候它的比例值是1 其他屏幕密度的参考比例都是以这个为依据。
2, 默认的drawble目录(一般是自己建的),和mdpi是一样的。将放到这个目录和放到drawble-mdpi目录是一样的效果。不过一般习惯性的放一些自定义selector或者点9的在这里。
现在我们来看, HTC one V手机的屏幕密度是252ppi, 那距离哪一个最靠近呢, 就是hdpi了。 所以当apk运行在这个手机上时,首先会去这个目录找。
下面是用常见的一些类型的手机总结的一个表格:
注意一点: 上面说的对应关系,都是首选目录, 那如果首选目录里面找不到呢?
Android选择策略
上面说到, 如果屏幕所对应的文件夹没有要找的,怎么办。这是很常见的,我们开发项目时一般不会去为每一个级别的屏幕去切一套。那样做只会让apk很大。所以一般性的我们只切一两个典型密度屏幕的。但是apk是有可能会运行在从ldpi到xxhdpi的各种级别的手机上。这个时候就需要根据一定的策略去寻找了。
Android系统寻找的步骤是这样的:
1, 去屏幕密度对应的目录去找。如果找到就拿来用。
2, 如果没找到,就去比这个密度高一级的目录里面去找,如果找到就拿来用。
3, 如果没找到就继续往上找。以此类推。
4, 如果到了xxhdpi目录还没有找到的话,就会去比自身屏幕密度低一级的目录去找,如果低一级的目录>=hdpi,找到了就拿来用。
5, 如果没找到, 就去mdpi目录去找, 如果找到了,就拿来用。
6, 如果没找到,就去默认的drawble目录里去找, 如果找到了就拿来用。
7 ,如果没找到,再去最低的ldpi目录里去找。如果找到了,就拿来用。
8, 如果没找到, 那就是没找到了, 无法显示。(不过一般不会出现这种现象,因为如果每个目录都没有这个的话,你是编译不过的)
这里有两点需要注意:
① 首先会去比自己密度高的目录里去找,这是因为因为系统相信,你在密度更高的目录里会放置分辨率更大的,这样的话这个会被缩小,但同时显示效果不会有损失,但是如果优先去低一级别的目录去找的话, 找到的就会被放大,这样的话这个就会被拉扯模糊了。
eg 同一张,你在mdpi和xxhdpi目录各放了一份, 这个应用你现在运行在hdpi的手机上, 那应用会选择哪张呢。答案是xxhdpi目录里的。即便hdpi离mdpi更近一点!
②,如果在mdpi里找不到是不会直接去ldpi里找的, 而是先去默认的drawble目录里找,这是drawble目录和drawble-mdpi是一个级别的。
下面用一张流程图来总结:

(注: 以上流程图是我通过做实验总结出来的,如有谬误还望指出。)
Android系统对的缩放规则
上文中提到如果在手机对应的目录没有找到,就会按照一定的策略去其他目录找,那找到了以后就原图显示么? 非也。
对于放在不同目录下的, 系统会按照一定比例对原始的进行放大或者缩小, 具体的放大缩小比例可参考下表, 所在目录和对应的屏幕密度是相同时缩放比例为1,也就是原图显示,而横向的比例表示分别放在该密度手机上运行时被缩放的比例。
对原始的缩放倍数。
上表几点值得注意的地方:
①, drawable目录和drawable-mdpi目录和dp到px的转换关系是一样的。
②,当你放一个120px180px的到drawable-hdpi目录,如果此应用运行在一个xhdpi的手机上,则这个会被拉扯到160px240px。
③, 最后一行dp->px, 说明了在代码或者布局文件中声明一个dp值, 这个值在不同屏幕密度的手机中会被乘以不同的倍数。 比如你在布局文件中写了一个宽和高分别为120dp和180dp的LinearLayout, 那么当这个应用运行在xhdpi的手机上时(比如上面那个常见手机表中的中兴U985手机),它的实际像素就会被转换为240px360px。 如果运行在ldpi的手机上,就变成了90px135px。 但是在这两个手机中显示的区域大小从肉眼看,是一模一样大的。(这点作为后面内容的一个引子,“看起来”一样大,这就是Android的一个神奇的地方)

我们来做个试验
试验材料:
① 一张120px180px的
② 四部手机, 具体参数参考上面的一张表格。三星 Galaxy win pro 3218 (hdpi)、 HTC one V (hdpi)、 中兴U985 (xhdpi)、Google Nexus 7 (xhdpi)。
③ 我在布局文件里声明了3个View, 第一个位于左上角,是一个线性布局,宽和高指定为120dp180dp(注意是dp哦), 第二个位于右上角,是一个ImageView,内容就是上面这张120px180px的, 第三个位于左下角也是一个线性布局,固定宽高,是120px180px。
我将这个放到一个Android工程里的drawable-hdpi目录
从上面的那种缩放关系表中我们可以知道,从hdpi目录中取, 运行在hdpi手机上宽高保持原始值,,运行在xhdpi手机上,宽高会乘以4/3, 也就是说会被拉扯变大, 但是的实际显示效果,即“视觉大小”怎么样呢。
下面是运行后的效果:
如图: 黑色区域是120dp180dp的View, 蓝色区域是120px180px的, 灰色区域是120px120px的View。
1, 可以看到使用dp的View(黑色区域)在不同分辨率,不同屏幕尺寸,不同屏幕密度的手机下,视觉大小看起来是一模一样的。
但是他们的实际像素值是不一样的: 120dp180dp -> (hdpi) -> 180px270px, 而120dp180dp ->(xhdpi)-> 240px360px。 由于屏幕密度的不同,缩放以后的像素可以显示出一样的视觉大小。
2, 蓝色的视觉大小也是一样的, 由于放到了hdpi目录下, 所以前两个手使用的是的原始像素120px180px, 而后两个手机对进行了放大, 参考上面的屏幕密度缩放关系表, 放大了4/3倍。 我通过对屏幕的截图,测量下来的结果的确是放大了这么多, 分别为160px240px。 由于屏幕密度的不同,它们显示出来的视觉大小是相同的。
3, 但是使用固定像素值的View就没那么幸运了, 它在hdpi的手机上看起来要比在xhdpi的手机上大一些。 要是在屏幕密度相差更大的手机上看的话, 这个区域的大小会相差很大。 这就是为什么Android推荐使用dp作为View的尺寸,而不是真实像素的原因了。
4, 经过反复试验,(实验结果就不贴图了,很多),得出一个结论,使用哪个目录下的(前提是只放在某一个目录中),在所有,不管是分辨率还是屏幕尺寸还是屏幕密度,3个参数都在改变的情况下,显示的视觉大小都和运行在这个目录对应屏幕密度手机上时的大小是一样的。
UI给工程师切多大图是合适的。
说说我之前走的冤枉路吧。
在之前, 设计师的交互和视觉设计都是基于480800的界面, 切图的时候会以480800为基础切一版, 然后在给所切的宽和高乘上个4/3,然后在出一版。
比如同一个120180的, 就会出两个版本, 一个是120180的一个是160240的。分别放到hdpi目录和xhdpi目录。
吃到的苦头是,UI很累, apk很大。T^T
这番探究下来, 发现直接基于7201280的视觉稿切一版就可以了。 将只放到xhdpi目录中,这样系统会在不同密度屏幕的手机中对进行合理的缩放, 而之前这个缩放工作竟然是人工完成的!
另: 如果想在xxhdpi的手机上显示的很好, 也可以基于1080P的屏幕设计, 这样的话就兼容所有低密度屏幕的手机, 而且也不会出现被拉扯的现象。

1、在大屏幕设置中找到“显示设置”或“图像设置”等相关选项。
2、进入设置后,找到“视频制式”或“制式”等选项,选择“自动”或“自适应”。
3、没有“自动”或“自适应”选项时,可以手动选择NTSC或PAL制式,但是需要根据实际情况选择,否则可能会出现图像失真等问题。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/13372026.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-23
下一篇 2023-07-23

发表评论

登录后才能评论

评论列表(0条)

保存