从上图我们通过计算可以得出,目前的设备前四个占据大份额(77.6%)的分辨率的手机的屏幕长宽都是按照比例缩放的。
1.Android系统的图片寻找机制对放在xhdpi,xxhdpi等不同密度的图片会根据手机的密度寻找最合适的文件夹下的图片,然后进行根据密度的比率进行放大,缩小处理。
2.意味着一张背景图如果是7201280的大小的话,放在上述分辨率的手机上都是可以无变形缩放的。目前我们的设计师大多情况都是按照ios的手机来设计界面的,主流是按照iphone6(7501334)
一计算,你也会发现,这个也是和上述主流的分辨率长宽也是对应的比率关系。
结论:我们设计师如果按照iphone6设计屏幕的话,Android是可以一套图片就可以达到界面的适配,
只不过放在xhdpi或者xxhdpi下面,Android SDK会自动屏幕尺寸选择对应的资源文件进行渲染,如SDK检测到你手机dpi是320的话会优先到drawable-xhdpi文件夹下找对应的图片资源,注意只是优先,假设你手机dpi是320,但是你只在xxhpdi文件夹下有对应的图片资源文件,程序一样可以正常运行。所以理论上来说只需要提供一种规格的图片资源就ok了,如果只提供hdpi规格的图片,对于大分辨率的手机如果把图片放大就会不清晰,所以需要提供一套你需要支持的最大dpi的图片,这样即使用户的手机分辨率很小,这样图片缩小依然很清晰。
既然一套图可以达到界面的适配,那应该采取哪一套图,又应该放在Android下面的drawable还是mipmap下面,如果是放在drawable下面,又应该放在drawable-xxhdpi,drawable-xhdpi,drawable-xxxhdpi还是别的密度下面呢?带着这个疑问,接着看下面的图:
Android的dpi分布
Androidiosmdpi区间的手机,dp=px。在3GS上,1point=1px。xhdpi区间的手机,1dp=2px。在iPhone4上,1point=2px。在iPhone5上,1point=2px。在iPhone6上,1point=2px。xxhdpi区间的手机,1dp=3px。在iPhone6 plus上,1point=3px。
分析:从上图我们可以看出ios的2x图片就是对应Android的xhdpi的密度,ios的3x图片就是对应Android的xxhdpi的密度。
结论:前面我们得到结论是Android下面也是一套图也是可以适配的,意味着我们将ios的3x图放在xxhdpi文件夹下面,或者拿ios2x的图片放在xhdpi下面都是能适配主流的分辨率机型。但是根据前面的分析,为了防止放大不清楚的情况,Android最好是放在xxhdpi下面。
有人可能会有疑问,放在xxhdpi密度下面的图片,会不会内存增大,毕竟图片会变大,那我们再进行内存层面的分析:
经测试:
3.首页2x的图片放在xxhdpi下面,在xxhdpi密度的手机下显示:width = 750 height = 1294 bitmap = 3791kb
4.首页2x的图片放在xhdpi下面,在xxhdpi密度的手机下显示:width = 1125 height = 1941bitmap = 8529kb 大小是放在xxhdpi的2.25倍。
分析:有个 drawable的density 和真实屏幕的 targetDensity,因为 scaledWidth 和 scaledHeight 是由 width 和 height 乘以 scale (手机真实的屏幕密度/drawable的密度)得到的。我们看到 Canvas 放大了 scale 倍,然后又把读到内存的这张 bitmap 画上去,相当于把这张 bitmap 放大了 scale 平方倍。
结论:虽然上面说了xxhdpi下的图片在加载的过程内存消耗得更少,但是前提是指同一张图片从xxhdpi一到xhpi下面的话,加载内存一般会扩大2.25倍。但是由于3x的图片本来长宽本来就比2x的图片长宽的像素点就是多1.5倍。所以一般在这个层面,如果我们把ios的2x图片放在xhdpi下面和把ios的3x图片放在xxhdpi下面,对于同一个真机加载消耗的内存基本是一样的。
5.另外很多人对图片是放在mipmap下面还是drawable下面总是有疑问,对放在什么文件夹下面没有什么概念,对此官方有个解释:
Drawables may be stripped out as part of dp-specific resource optimisation. But mipmaps will not be stripped. So it's best to put app icons under mipmaps.
Here is more detail written on google documentation page:
Different home screen launcher apps on different devices show app launcher icons at various resolutions. When app resource optimization techniques remove resources for unused screen densities, launcher icons can wind up looking fuzzy because the launcher app has to upscale a lower-resolution icon for display. To avoid these display issues, apps should use the mipmap/ resource folders for launcher icons. The Android system preserves these resources regardless of density stripping, and ensures that launcher apps can pick icons with the best resolution for display.
总结下:上面话就是想表达放在drawable的图片会对不适用真机屏幕密度的资源进行移除,放在mipmap依然会保留下各个密度的图片,所以为了保证桌面图标的显示质量因此放在mipmap下面,其他的图标建议都放在drawable文件夹下面吧。
6.此文发出之后,好多人提出:mipmap 中图片适配内存消耗会更小些?所以专门针对这个问题,反编译了几个google的app
我查了下据说放在 mipmap 减少内存的原因是因为:比如 493 的 ppi 的手机,会到 xxxhdpi 下面找图片,然后自动按照 493 和 xxxhdpi 的手机密度比进行缩放加载,从而不用加载 xxxhdpi 的内存大小的图片,以达到内存优化,但是这个 drawable 文件夹下面也是有这样的机制的,除了这个内存优化,其他没有找到官方的解释,另外通过反编译 google 开发的几个 app,都发现 google 的 app 中的 mipmap 文件夹下面基本都是放 launcher 图标,其他的图标都是放在 drawable 下面的。
最终结论:那么经过上面一系列的分析,如果你们的设计师是按照iphone6来设计界面的话,Android的屏幕适配最好就是将ios的3x图片放在Android的drawable-xxhdpi文件夹下面。
如果个人描述有什么不准确的地方,烦请指出,谢谢!!