[关闭]
@TryLoveCatch 2022-04-26T08:50:37.000000Z 字数 2585 阅读 1983

Android知识体系之drawable文件夹顺序

Android知识体系


mipmap和drawable

mipmap文件夹只是用来放置应用程序的icon的

  之前,我们都是把应用程序的icon图标和普通的图片资源一起放到drawable文件夹下的,这样看上去就会比较杂乱,android现在专门给了一个文件夹来访应用icon图标。

dpi表

drawable遍历顺序

  1. 假设手机dpi为403,分辨率为1080*1920,那么我们就处于320-480之间,属于xxhdpi的范围。
  2. 假设图片大小为270*480,名字为img1.png
  3. xml如下:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. >
  7. <ImageView
  8. android:id="@+id/image"
  9. android:layout_width="wrap_content"
  10. android:layout_height="wrap_content"
  11. android:src="@drawable/android_logo"
  12. />
  13. </LinearLayout>

测试一

将图片放到drawable-xxhdpi下面,我们运行,可以看出来,很正常,没什么问题。

测试二

将图片移动到drawable-xhdpi下面,然后重新运行一下程序,我们会发现,相比于"测试一",图片好像变大了,可能不明显,我们继续

测试三

将图片移动到drawable-mdpi下面,然后重新运行一下程序,哈哈哈,这次明显了吧,确实变大了。

小结

    为什么会被放大呢?当我们使用资源id来去引用一张图片时,Android会使用一些规则来去帮我们匹配最适合的图片。
    什么叫最适合的图片?比如我的手机屏幕密度是xxhdpi,那么drawable-xxhdpi文件夹下的图片就是最适合的图片。因此,当我引用img1.png这张图时,如果drawable-xxhdpi文件夹下有这张图就会优先被使用,在这种情况下,图片是不会被缩放的。
    但是,如果drawable-xxhdpi文件夹下没有这张图时,系统就会自动去其它文件夹下找这张图了,优先会去更高密度的文件夹下找这张图片,我们当前的场景就是drawable-xxxhdpi文件夹,然后发现这里也没有img1.png这张图,接下来会尝试再找更高密度的文件夹,发现没有更高密度的了,这个时候会去drawable-nodpi文件夹找这张图,发现也没有,那么就会去更低密度的文件夹下面找,依次是drawable-xhdpi -> drawable-hdpi -> drawable-mdpi -> drawable-ldpi。
    总体匹配规则就是这样,那么比如说现在终于在drawable-mdpi文件夹下面找到android_logo这张图了,但是系统会认为你这张图是专门为低密度的设备所设计的,如果直接将这张图在当前的高密度设备上使用就有可能会出现像素过低的情况,于是系统自动帮我们做了这样一个放大操作。
    那么同样的道理,如果系统是在drawable-xxxhdpi文件夹下面找到这张图的话,它会认为这张图是为更高密度的设备所设计的,如果直接将这张图在当前设备上使用就有可能会出现像素过高的情况,于是会自动帮我们做一个缩小的操作。

测试四

将图片移动到drawable-xxxhdpi下面,然后重新运行一下程序,哈哈哈,确实缩小了,符合上面的结论。

drawable-nodpi

这个文件夹是一个密度无关的文件夹,放在这里的图片系统就不会对它进行自动缩放,原图片是多大就会实际展示多大。
但是要注意一个刚才说的加载顺序,drawable-nodpi文件夹是在匹配密度文件夹和更高密度文件夹都找不到的情况下才会去这里查找图片的,因此放在drawable-nodpi文件夹里的图片通常情况下不建议再放到别的文件夹里面。

放大缩小的倍数

在看一下上面的dpi表

每一种密度的dpi范围都有一个最大值,这个最大值之间的比例就是图片会被系统自动放大的比例。

测试一

  1. 将img1.png移动到drawable-mdpi文件夹下
  2. 打印ImageView的宽和高
  1. "图片宽度:" + imageView.getWidth()
  2. "图片高度:" + imageView.getHeight()

mdpi密度的最高dpi值是160,而xxhdpi密度的最高dpi值是480,因此是一个3倍的关系,那么我们就可以猜测,放到drawable-mdpi文件夹下的图片在xxhdpi密度的设备上显示会被放大3倍。对应到img1.png这张图,原始像素是270*480,放大3倍之后就应该是810*1440像素。
运行程序,打印如下:

  1. 图片宽度:810
  2. 图片高度:1440

测试二

再来验证一次
将img1.png移动到drawable-xxxhdpi文件夹下。
xxxhdpi密度的最高dpi值是640,480是它的0.75倍,那么我们就可以猜测,放到drawable-xxxdpi文件夹下的图片在xxhdpi密度的设备上显示会被缩小至0.75倍。270*480的0.75倍应该是202.5*360,由于像素不支持小数点,那么四舍五入就应该是203*360像素。

结论

假设手机dpi处于320-480之间,属于xxhdpi的范围

1. drawable遍历顺序:xxhdpi-->xxxhdpi-->nodpi-->xhdpi-->hdpi-->mdpi-->ldpi
2. 如果图片存放的位置和手机所处的dpi不一致的时候,就会按照dpi表里面每一个范围的最大值,按照比例进行缩放。
3. 最佳放置图片资源的文件夹就是drawable-xxhdpi,因为xxxhdpi得设备比较少,而如果放到低dpi的文件夹下,在xxhdpi里面就会放大,图片分辨率的变大,会造成bitmap变大,增加内存开销。

为什么图片的分辨率会变大,bitmap究竟变大了多少?Bitmap的大小

参考

Android drawable微技巧,你所不知道的drawable的那些细节

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注