Android 最佳屏幕适配方式探索

android资源文件夹使用限定符进行命名

一:创建限定符文件夹

使用android studio自带的工具进行创建

参考下图

其中Available qualifiers 即为支持的所有限定符,用户可以选中多个限定符,生成类似values-zh-ldltr-sw360dp-xxhdpi-360x640 这种文件夹

二:限定符优先级

按照如下顺序排列(其实就是上图中创建限定符文件夹时studio列出的顺序)

(移动国家代码)-
(语言和区域)-
(布局方向)-
(smallestWidth)-
(可用宽度)-
(可用高度)-
(屏幕尺寸)-
(屏幕纵横比)-
(圆形屏幕)-
(屏幕方向)-
(UI 模式)-
(夜间模式)-
(屏幕像素密度 )-
(.....)-
(屏幕绝对尺寸dp)-
(API级别)

三:系统读取限定符文件夹的顺序

查找顺序

1:根据高到底的限定符优先级顺序开始检索文件夹(根据上面的优先级开始查找)

2:(排除异己)如果检索到匹配限定符,且此限定符不是像素密度限定符,则将该限定符属性与设备属性冲突的 文件夹排除
(比如第一优先级是移动国家代码,移动国家代码包含MCC和MNC 如果匹配到了MCC 则将含有MNC的文件夹排除,但是在像素密度限定符上除外 比如设备是XXhdpi 不会将mdpi排除)

举例
drawable-fr-rCA/ 目录与 en-GB 语言区域冲突,因而被淘汰。
drawable/
drawable-en/
drawable-fr-rCA/(淘汰)
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/

3:(限定)如果检索到匹配限定符,且此限定符不是像素密度限定符,则将不含该限定符的文件夹跳过 如果没有检索到,则按照优先级顺序进行下一个限定符的检索
举例
drawable/(跳过)
drawable-en/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/(跳过)
drawable-port-notouch-12key/(跳过)

4:返回并重复第 第 3 步和第 4 步,直到只剩下一个目录为止。
在此示例中,屏幕方向是下一个判断是否匹配的限定符。因此,未指定屏幕方向的资源被跳过:
drawable-en/(跳过)
drawable-en-port/
drawable-en-notouch-12key/(跳过)

5:当满足一级为B级的限定符 但不满足B级后面的C级限定符时则淘汰该BC文件夹 如果B级下面的所有所有C级均已经被淘汰且不存在单独的一级为B的文件夹
则直接进入一级为C级的限定符(其实就是下一个优先级的限定符)进行限定 抛弃所有一级为B限定符的文件夹
在此示例中 en限定符级别高于sw限定符 系统优先进入en下匹配,进入en后在进入屏幕尺寸限定符,但sw360不符合设备配置,且当前就不存在单独的drawable-en 目录
则此时跳出之前已选定的en限定符 直接淘汰drawable-en-sw360 开始从en的下一个限定符(sw)进行匹配
drawable-en-sw360/(淘汰)
drawable-sw320/

6: 在匹配屏幕尺寸(注意是尺寸 不是密度)时,如果没有匹配到,则会使用小于当前屏幕设计的资源。但是如果唯一可用的资源大于当前屏幕(比如没有drawable这种),系统将不会使用这些资源,将会崩溃。
在此示例中 设备尺寸为300dp 不满足最小的sw320 又不存在drawable这种不限定的文件夹 则直接崩溃
drawable-sw320/(淘汰)
drawable-sw360/(淘汰)
drawable-sw400/(淘汰)

tips :注意上面描述时 使用淘汰和跳过两个方式,跳过是指暂时跳过往下检索 但是任然可能在找不到合适的资源时回头再用 但是淘汰就是彻底淘汰 不会再次使用

四:限定符在dimens适配中的规则及建议

首先看一下在vivo生产的常见机型中 屏幕分为以下几类

1:800*480  854*480  低分辨率的老机器,屏幕密度1.5 横向宽度320dp 

2:960*540  中低分辨率老机器,屏幕密度1.5  横向宽度360dp

3:1080*720  中分辨率机器  屏幕密度2 横向宽度360dp

4:1920*1080  高分辨率   屏幕密度3 横向宽度360dp

5:2540*1440  超高分辨率   屏幕密度4 横向宽度360dp

一般来讲 UI输出的标注图一般会按照1080分辨率进行标注

常见的适配规则是使用屏幕密度进行区分适配

比如,项目中内置hdpi  xhdpi xxhdpi  xxxhdpi 等密度限定文件夹

以上述vivo的常见机型为例,所有常见机型涉及四种屏幕密度,看似刚好可以用四种密度的限定符来进行适配

一般的做法是省略为两个限定符, 保留hdpi和xxhdpi,以xxhdpi为基准分辨率将测量到的dp 整体缩小  缩小的倍数为320/360 然后将得到的dp填入到hdpi中 这样来保证800*480的机器上能等比例的缩小显示内容

但是这么做了之后就会发现问题

上述机型中有一个特例,那就是960*540的机器,这个机器符合hdpi标准,但是横向宽度却是360dp 也就是说在这个屏幕上使用的dp值应当和xxhdpi屏幕上是一致的。

传统的解决方案就是新建一个hdpi-960x540的value文件夹,同时拷贝一份xxhdpi中的值到hdpi-960x540当中

使用smallestWidth可以很好的解决该问题

五:smallestWidth简介

smallestWidth适配,或者叫sw限定符适配。指的是Android会识别屏幕可用高度和宽度的最小尺寸的dp值(其实就是手机的宽度值),然后根据识别到的结果去资源文件中寻找对应限定符的文件夹下的资源文件。

创建smallestWidth限定符文件夹一般如下图所示

使用这种方式编写dimens的最大好处就是可以不用在关心设备的屏幕密度了(其实你以前也没怎么关心),而且这种方式在适配时有更大的宽容度。

以四种举出的vivo机型为例子,很容易可以区分为以下两种sw

1:value-sw320

2:value-sw360

那么理论上我们只需要创建这两个限定符文件夹就可以解决之前遇到的问题,但需要注意的是smallestWidth表示的是最小宽度,也就是说一台设备的宽度必须大于或者等于sw的数值才会匹配上,如果整个项目里面都没有找到这个数值的文件夹,就会出现崩溃(参照三-6中的描述)

因此建议建立一个默认的value文件夹来存储默认值防止崩溃,事实上我们只需要准备两个文件夹 

1:value (将360dp为基准按照倍数为320/360的比例进行缩放的标注)

2:value-sw360(用来存放以1080分辨率UI标注图为基准的标注)

即可满足现有的需求

TIPS : 虽然以上两个文件夹可以覆盖目前所有已知的机型,但仍然存在某些例外情况,比如公司新开发的机型,或者一些可以设置屏幕宽度dp的机型,因此建议在有些地方使用动态获取屏幕宽度的方式计算出准确的值进行适配

六:切图适配规则

存放到资源目录中的切图与dimens标注的不同之处在于,图片会涉及到内存占用,乱放文件夹会导致图片被从资源中引用是占用大量的内存

一般要使用密度限定符文件夹来保存图片,这样图片在被系统加载时会被缩放到响应的倍数,以合适的分辨率进行显示,占用的内存也在合理的范围内

一般来讲官网的UI设计师会提供三套图

1:1920*1080 为基准的切图均放在 drawable-xxhdpi文件夹下 

2:960*540 的切图放在 drawable-hdpi-960x540 文件夹下

3:800*480 的切图放在 drawable-hdpi 文件夹下

这样的话 其实是要维护三套切图,思考到960*540的机器存量极少

drawable-hdpi-960x540 这个文件夹是否可以去掉。我们按照上文提供的资源加载逻辑,模拟去掉此文件夹的场景

因为960*540的屏幕密度是hdpi 那么该机型下自然会去寻找hdpi文件夹下的图片,但是hdpi下的图片是为屏幕宽度为320的机器适配的,现在放到360的机器上可能就不合适

尝试使用sw新规则来适配图片

建立drawable-sw360文件夹存储图片,但是图片是需要指定基准密度的 此处因为使用的是1920*1080的基准屏幕 故密度是xxhdpi 于是再添加xxhdpi限定符

修改drawable-sw360为drawable-sw360-xxhdpi文件夹

系统优先匹配宽度,然后在进行密度缩放。这样就可以去掉drawable-hdpi-960x540 文件夹,让960*540的机器从xxhdpi中获取资源图片。

七:切图被加载后占用内存的规则

1:手机在加载图片时,会先查找自己本密度的文夹下是否存在资源,不存在则会向上查找,再向下查找,并对图片进行相应倍数的缩放:

2:如果在与自己屏幕密度相同的文件夹下存在此资源,会原样显示出来,占用内存正好是: 图片的分辨率*色彩格式占用字节数;

3:若自己屏幕密度相同的文件夹下不存在此文件,而在大于自己屏幕密度的文件夹下存在此资源,会进行缩小相应的倍数的平方;

4:若在大于自己屏幕密度的文件夹下没找到此资源,则会向小于自己屏幕密度的文件夹下查找,如果存在,则会进行放大相应的倍数的平方,这两种情况图片占用内存为:

占用内存=图片宽度 X 图片高度/((资源文件夹密度/手机屏幕密度)^2) * 色彩格式每一个像素占用字节数

因此上述六中让960*540的机器从xxhdpi中获取资源图片的行为不会造成机器内存占用激增。可以放心使用

八:总结

按照上述的理论优化资源文件夹后为

value

value-sw360

drawable

drawable-hdpi

drawable-nodpi

drawable-sw360-xxhdpi

上述内容有一部分来自于其他大神的文章摘抄,本用于自己学习记录所用,由于之前写的比较仓促没有记下网址,此处先表示感谢,如有朋友看到类似的的文段,实属必然,后面我会做好记录。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值