Android资源文件匹配规则及屏幕适配方案

在运行时,Android系统会根据当前的设备设置自动寻找合适的资源。为不同的设备提供不同的资源,主要是利用特殊命名的资源文件夹来实现的。

 

资源文件命名:

  • Android工程res目录下资源文件的命名格式:

资源名-属性1-属性2-属性3-属性4

  • 资源名的取值有:drawable, values, layout, anim, raw, menu, color, animator等
  • 各属性的位置顺序必须遵守优先级从高到低排列,否则编译不过。以资源文件values为例,各属性按优先级从高到低的排序为:

values-mcc310-en-sw320dp-w720dp-h720dp-large-long-port-car-night-ldpi-notouch-keysexposed-nokeys-navexposed-nonav-v7

 

屏幕宽度,高度的优先级在dpi之前,但是分辨率(1280x720)的优先级要在dpi之后

  • 属性说明:

values-mcc310(sim卡运营商)-en(语言)-sw320dp(屏幕最小宽度)-w720dp(屏幕最佳宽度)-h720dp(屏幕最佳高度)-large(屏幕尺寸)-long(屏幕长短边模式)-port(当前屏幕横竖屏显示模式)-car(dock模式)-night(白天或夜晚)-ldpi(屏幕最佳dpi)-notouch(触摸屏模类型)-keysexposed(键盘类型)-nokey(硬按键类型)-navexposed(方向键是否可用)-nonav(方向键类型)-v7(android版本)

 

资源文件匹配

  • 匹配是从最高优先级别的属性开始,排除跟系统配置不同的资源文件,而不是优先选择匹配到的属性数量最多的资源文件,例如:系统配置为values-en-normal-hdpi的手机,values-en匹配比vaues-normal-hdpi更合适。
  • 对于属性是屏幕大小(screen size),系统的匹配规则是"向下最佳匹配",即如果找不到能跟当前屏幕匹配的资源,比当前更小的屏幕的资源就会被使用(比如,一个large-size屏幕将会在必要的时候使用normal-size屏幕的资源文件);如果唯一可选的资源比当前的屏幕大,系统不会使用它们并且你的程序会崩溃。
  • 如果属性是屏幕像素密度dpi(device screen density),Android会选择最接近屏幕像素密度的一个,匹配规则如下图,可根据后面的测试结果对比。 (Android比较偏向于将原始的大图片缩放成 小的图片)。

  • 如果属性是分辨率(如480x800),向下读取与它最为接近的适配文件(即使向上会找到更为接近的,也取向下找到的结果).
  • 多属性混合时,匹配的信息越详细,优先级越高.假设现有一台手机的分辨率为1080x1920(xxhdpi),应用程序包含资源文件:values,values-1080x1920,values-xxhdpi,values-xxhdpi-768x1280,values-hdpi-480x800,values-xxhdpi-1080x1920.读取时这些资源文件的优先级为:values-xxhdpi-1080x1920 > values-xxhdpi-768x1280 > values-xxhdpi >values-hdpi-480x800, values-1080x1920 > values.
    values-xxhdpi-768x1280的读取优先级高于values-xxhdpi是因为values-xxhdpi-768x1280的分辨率小于1080x1920,符合向下读取最接近的分辨率,并且其提供的信息相对于values-xxhdpi更加详细.

 

虚拟机测试结果

  • 如果设备的屏幕密度为mdpi,当查找资源时,若res下只有ldpi,xhdpi,则会匹配到xhdpi;若res下只有ldpi,xxhdpi,则会匹配到ldpi。即屏幕密度为mdpi,当找不到确切资源时,应用会试着先向上查找(从默认资源文件开始),若仍匹配不到xhdpi及以下的资源,则从设备屏幕密度向下查找(从ldpi开始);若仍找不到,则从前一次向上查找的结束点(xhdpi)继续继续向上查找xxdpi。
  • 如果设备的屏幕密度为hdpi,当找不到确切资源时,应用会试着向上查找(xhdpi、xxhdpi),若仍匹配不到资源,则从设备屏幕密度向下查找(从mdpi开始,其次是默认资源文件、ldpi).

 

参考《Android资源图片读取机制

 

实践经验

 

如果项目中存放资源的资源文件夹只有一个,为values,此时查找资源不会出现问题;在适配ui时,为了适配低分辨率的手机可能会新增一个资源文件,如values-480x800,存放屏幕分辨率为480x800的相关资源.假设现有一台手机的分辨率为1080x1920(xxhdpi),运行该项目的应用程序,则会发现读取的资源文件夹为values-480x800!按照预期我们是希望在values文件加中读取!这是很常见的问题,解决该问题的方法为:把values文件夹改为values-xxhdpi,在values-xxhdpi文件夹中存放默认的资源文件,由于dpi属性的优先级高于分辨率,所以此时读取的资源文件夹为values-xxhdpi,而不是values-480x800.

然而上面的方法仍有问题,假设当前手机的分辨率为480x800(hdpi),会发现读取的资源文件夹为values-xxhdpi,而不是values-480x800!原因还是因为dpi属性的优先级高于分辨率,因此应该吧文件夹名称改为values-hdpi-480x800.

       总而言之,要适配不同分辨率资源文件夹应该为 values-xxhdpi 以及 values-hdpi-480x800(分辨率).

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章