Android UI适配总结(一)寻找最佳匹配资源
系统是怎么确定最佳资源的?
- 获取手机当前的基本配置信息(语言,横竖屏,屏幕密度,屏幕尺寸等等)
- 根据这些配置信息,排除apk包中与这些配置信息相矛盾的资源目录,假设系统语言是cn,那么所有的其他语言的目录都会被排除掉,注意系统并不会根据一个dpi的冲突而排除掉含有其他dpi的目录,dpi这个qualifier非常特殊
- 按照qualifirer的优先级,依次拿出配置信息中优先级最高的qualifier,去资源目录中寻找包含这个qualifer的目录,如果有,排除掉其他目录,根据配置中下一个优先级的qualifier继续匹配,如果没有,接着去拿下一个优先级的qualifier,继续寻找和排除,直到找到最合适的目录。
实例
假设我们放置同样名称的图片在如下目录
drawable/
drawable-en/
drawable-fr-rCA/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/
当前系统的配置为
Locale = en-GB
Screen orientation = port
Screen pixel density = hdpi
Touchscreen type = notouch
Primary text input method = 12key
匹配过程
首先qualifier的优先级如下,en-GB, port,hdpi,notouch,12key
* 根据en-GB,port,hdpi,notouch,12key这些配置信息,首先排除掉**drawble-fr-rCA目录,因为fr和en冲突
* 根据第一优先级的en-GB,找到如下三个目录,drawable-en/,drawable-en-port/,drawable-en-notouch-12key/,排除掉目录drawable/,drawable-port-ldpi/,drawable-port-notouch-12key/
* 接着获取下一个优先级的qualifier,port,找到了目drawable-en-port/,排除掉其他目录,就剩这一个了,那么就是这个了。
重点
-
虽然程序会频繁的获取资源文件,但是那些与当前配置信息相矛盾的目录会被永久排除掉,不会每次都去检查
-
假设系统根据screen size去寻找最匹配资源的时候,如果没有找到完全匹配的资源,系统会选择比当前配置小一点的screen size作为匹配,(例如一个large的屏幕会选择normal资源,如果找不到large资源的话)假设没有的话,只有xlarge的资源,系统不会选择使用这个资源,这个时候就会发生找不到资源的异常了。
-
资源限定符的优先级比匹配的qualifier多少更重要。例如在上面的例子中,drawable-en-notouch-12key/似乎更加匹配,但是port的优先级更高。
问题
假设匹配了最佳图片目录,但是发现目录里没有自己想要的图片会怎么样?
-
如果是mdpi中没有图片,可以去选择hdpi的目录里找寻图片,然后缩放
-
如果是large种没有图片,可以去normal中找寻图片
-
如果layout-port中没有布局文件,就去layout中找寻布局文件
-
如果values-cn-hdpi下没有dimen的话,有待研究
-
假设当前手机屏幕是hdpi,res目录下含有mdpi,hdpi,xhdpi,xxhdpi,但是hdpi目录下没有需要的图片,其他的目录下都包含,那么当前手机会选择哪个图片呢?
我的猜测是xxhdpi,因为xxhdpi(3)与hdpi(1.5)的比例正好为2,比从xhdpi(2)缩放到hdpi(1.5)更简单,但是经过测试发现手机加载的是xhdpi目录下的图片,所以我推测系统的逻辑是:首先是高dpi原则,也就是如果当前dpi下没有,那么就从更高dpi的目录下开始寻找,也就是xhdpi---》xxhdpi---》mdpi。为什么遵循搞dpi原则呢,因为从放大图片可能会导致图片失真,变模糊。