Android 项目中软件图标适配和mipmap文件夹的规则

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 项目中软件图标适配和mipmap文件夹的规则相关的知识,希望对你有一定的参考价值。

参考技术A 参考: android开发使用mipmap文件夹的正确姿势: px 、dpi 、dp

Android应用图标微技巧,8.0系统中应用图标的适配

测试的在华为手机Android 9.0系统中,但是在切换 targetSdkVersion 大于26和小于26的时候,并没有对图标进行原型切换,26前后对应的图标形状一样。可能是华为对这部分源码进行了修改,将mask层修改为圆角矩形。

mipmap 中的文件夹分别为

新创建的项目都会有这几个文件夹,那么这几个文件夹是怎样的呢?内部的规则是什么呢?都是怎样对应的呢?
讲解这些之前我们需要知道我们平常见到的一些尺寸单位的关系:

px (像素点)和 dpi (像素单位密度)之间的换算公式是:

px,dpi 和 dp 之间关系:

上边一些尺寸的基础知识,感觉很乱啊。。。
接下来就将一下 mipmap 下边几个文件夹的关系 表1-1:

上边 dp 对应 px 的比值我起名为 (luffy) 。
我们在开发的过程中,对图片的展示通常就两种:固定宽高,不固定宽高。
固定宽高会遇到的问题是放置的图片可能会模糊;不固定宽高可能就会和自己想要的尺寸不一样了。
我现在以不固定宽高的来说,比如给一个 TextView 设置 dropLeft ,这样就不能设置宽高,那么 ui 给的图片我到底该放置到哪个 dpi 文件夹里边才合适呢。因为我开发的是特定机器上的 app ,所以只需要一个 mipmap 文件夹就行了。
我现在将一张 32 * 32 的图片分别放到这六个文件夹里边,不固定尺寸的显示图片,并通过 方法 获取图片的宽高,测试机器的 dpi 是 480 。
记住两个数据:图片尺寸是 32 * 32 ;测试机是 480dpi 。
结果如下 表1-2:

结果是同一张图片放到不同的文件夹中,显示的尺寸是不一样的,因为测试机是 480dpi ,对应的本命 mipmap 文件夹是 mipmap-xxhdpi ,所以这个文件夹中的图片在这个测试机上都会原尺寸显示。其他的文件夹中的图片都会根据1-2表格中的 dp 和px的换算比例进行换算。比如,1-2表中 mipmap-xxhdpi 对应的 luffy 是 3 , mipmap-hdpi 的 luffy 值是 1.5 ,如果我们将 32 * 32 的图片放到 mipmap-hdpi 文件夹中,其他文件夹中不放置,软件展示图片的时候就会获取 mipmap-hdpi 文件夹中的图片,显示的效果我们知道是 64 * 64 ,再看对应着刚说的 luffy 值,是不是看出点什么?好像不同文件夹中的图片显示的效果和luffy值有关啊。

比如 ,当将图片放置到mipmap-hdpi 文件夹中:

那么如果我们想不管从哪个文件夹获取图片,展示的都是 32*32 ,那好说啊,按照这个公式,获取不同文件夹中需要放置的图片尺寸。比如 mipmap-hdpi 放置 16 * 16 的图片,就可以在我的测试机上展示 32 * 32 的效果了。

我上边一直说的展示尺寸都是 px ,那么在不同的机器上同时展示 32 * 32 的效果,根据上边的公式可以实现,但是展示的效果肯定各不相同。
上边的需求是我在做特定机器时,只有一种分辨率,一种 dpi ,那我想把所有 mipmap 文件夹都塞满,而且展示的效果都一样,就需要上边的公式。

当手机上不同的机器,不同的 dpi 展示同一种效果时,也就是占用屏幕相同的比例时,那表示这个效果的值就是 dp ,相同的 dp 在不同的机器上展示的效果基本相同,比如我想在 480dpi 的机器上展示的效果要和 320dpi 一样,那就需要它们展示的 dp 一样,我们展示一个 32dp*32dp 的图片。根据公式: px=dp*(dpi/160) 可以得到 32 * luffy=?px ;那么 480dpi 对应的 luffy 值是 3 ,所以 480dpi 对应的 mipmap 中的图片尺寸是 96px * 96px , 320dpi 对应的 mipmap 中的尺寸是 64 * 64 。

要在不同的机器上展示 32dp*32dp 的图片一张表格展示: 1-3

其他 dp 的图片都可以按照这个规则展示。

当合适的 mipmap 文件夹中没有对应的图片的时候,会优先往高的找,会优先找最近的

Android中drawable和mipmap到底有什么区别

老项目代码中发现有的图片放到了drawable中, 有的图片放到了mipmap中, 开发时秉承哪个目录下文件多放哪里的原则, 偶尔有疑惑搜一搜文章, 看到了结论也就这么使用了, 不过今日有时间, 依次检验了一下文章中的内容, 发现和实际的表现出入甚远.

常见的几种结论

Case 1 drawable会剔除其它密度, mipmap会保留全部(实际上最终的结论和这个有关联)

当xhdpi密度的手机在加载apk的时候Google是有一个优化的,是会剔除drawable其他密度的文件,只保留一个基本的drawable和drawable-xhdpi的文件,而mipmap是会全部保留的。

检测方法也比较简单, 在drawablemipmap不同密度的问价夹下分别放入同一类图片(图片标文字用于检查), 分别打包并检查其大小

Case1.1 安装包与应用大小

安装包大小应用大小
drawable13.3 MB (14,016,841 字节)14.04MB
mipmap13.3 MB (14,017,191 字节)14.04MB
###### 结论1.1
由此可见, 虽然两个安装包大小略有差异, 考虑到图片本身的大小(每张图片都在1Mb作用), 可以认为放入drawablemipmap文件夹中的图片在安装包和应用安装后没有差异

Case1.2 应用内表现

排除安装包的情况, 我们看一下在应用内的表现情况(通过adb shell wm density保证只修改手机的dpi信息)

100420800
drawable
mipmap
结论1.2
由此可见, 文件不论放在哪个目录下, 在手机中都会正确的显示为其匹配的图片资源

Case 1.3 应用内缩放

如果一个 imageView 有缩放动画,使用 drawable 下的图片,会一直使用一张来缩放图片实现 imageView 缩放动画。 如果使用 mipmap 下的图片,会根据缩放程度自动选择比当前分辨率大而又最接近当前分辨率的图片来做缩放处理。

这个可能大家见得不是很多, 不过既然有这种说法, 那就来测试一下

drawable
小缩放比例大缩放比例
mipmap
小缩放比例大缩放比例
结论1.3
可以看到在缩放动画的过程中, 一直显示的都是同一个动画

Case 2 应用内性能

Google对mipmap的图片进行了性能优化, 使其可以表现的更好

drawable
性能检查一览MEMORY10次图片加载平均时间
146
mipmap
性能检查一览MEMORY10次图片加载平均时间
151
结论2
可以看到, 加载单张图片的情况下其性能基本一致,不排除图片太小/太少性能优化不明显的情况, 不过尝试单证图片重复加载的情况下依旧表现为性能相近的情况, 或许时只针对特殊类型有优化? 如各位知道的更详细, 欢迎和我进行交流。

Case3 启动图标

在查阅资料的时候, 发现多次提及minmap应用只放入应用的启动图标, 使其可以得到优化.

100dpi420dpi800dpi
结论3

可以看到, 不同dpi的情况下应用图标的显示情况都是一致的. 其应用图标切换的边界值也是一致的. 关于420dpi和800dpi显示效果一样的情况, 因为种种原因, 应用图片在选择图片资源的时候, 需要将密度扩大25%左右1.

看到这里大家应该和我有着一样的疑惑, 既然drawable和mipmap下图片的表现不论是安装包还是应用内, 甚至连官方文档都这么说了, 为什么各种测试结果下来, 两者的表现基本的一致呢?

罪魁祸首 Bundle(.aab)

提到Bundle(.aab)国内的开发者可能都比较陌生, 甚至不少之前做过Google Play上架应用的都不是很熟悉. 这个其实在我们每次手动打包的时候都会出现。

简单来说.aab包一般用于Google Play商店使用, 在你从Google Play商店下载应用时, 它会根据你手机的实际使用情况来下载不同drawable中的资源. 以期望达到减少安装包大小的目的. (一般情况下手机dpi不会改变, 其它密度下的资源文件直到应用卸载时都不会被使用).

下面的测试使用到的工具为bundletool2, 简单来说, 就是模拟从Google Play下载应用和安装应用的过程.

安装包比较

安装包(apks)大小应用大小
drawable5.91 MB (6,201,543 字节)6.22MB
mipmap12.6 MB (13,230,670 字节)13.26MB

应用内表现

100420
drawable
mipmap
可以看到, 当图片放到`drawable`相关文件夹下的时候, 通过.aab包安装的应用会比放到`minmap`的下的应用小许多, 并且应用内更改dpi的时候页可以看到其不再能自动根据当前dpi选择对应的图片了。

结论

那么通过以上的测试, 我们可以得到以下结论了 以下结论均不涉及mipmap的性能优化相关(主要是暂未能设计好一个比较明确的测试对比) 以下测试机型为pixel 7, 测试Android版本为13

  1. 当应用构建为.apk的情况下, drawablemipmap文件夹下的资源表现无差异, 不论是应用内表现还是在启动器(应用图标)中表现.
  2. 当应用构建为.aab的情况下, drawable文件夹下的资源会寻找匹配的设备密度保留, 不匹配的资源会被删除已保证apk的大小.而mipmap文件夹下的资源文件会全部被保留.

那么我们应用内使用的图片就可以放到任意的目录下么?

如果你的应用是通过.apk分发安装的, 原则上是没有区别的. 但是Google对相关的目录也有推荐说明:

可以看到, mipmap目录下原则上只能保存应用图标. 同样, 其官方项目单密度资源项目也都是这样使用设计这两个文件夹的.

.aab包内mipmap保留机制是否是只适用于应用图标

测试后可以发现, mipmap的保留机制适用于mipmap下所有的图片资源, 不论是否为应用图标

相关代码可以访问我的GitHub

Footnotes

  1. developer.android.com/training/mu…

  2. github.com/google/bund…

作者:clwater
链接:https://juejin.cn/post/7179187950050082873

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。


相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

全套视频资料:

一、面试合集

二、源码解析合集


三、开源框架合集


欢迎大家一键三连支持,若需要文中资料,直接点击文末CSDN官方认证微信卡片免费领取↓↓↓

以上是关于Android 项目中软件图标适配和mipmap文件夹的规则的主要内容,如果未能解决你的问题,请参考以下文章

Android-8.0系统中应用图标的适配

Flutter 修改应用程序的名称和图标

Android mipmap 图标作为状态(通知)栏图标

Android Studio中的 Image Asset Studio(图标生成工具)

用于图标的 Mipmap 可绘制对象

android studio selector 怎么引用mipmap