zoukankan      html  css  js  c++  java
  • Android:Toolbar的图标尺寸问题

    之前一直使用的是Material Design的图标库,下载下来以后直接放入了对应文件夹,什么尺寸对应什么dpi都没有仔细研究过。

    最近在Toolbar上添加几个不是MD图标库内的图标时发现,放入的图标在显示时有时候感觉被放大了,有时候又显得模糊。让我对这个图标的尺寸和显示系统产生了好奇,折腾了一番,终于算是基本弄清楚了。

    PX、DP和DPI

    首先复习一下屏幕像素密度的知识:

    1. px:像素点
    2. dpi:像素密度,即每英寸像素数
    3. dp:屏幕密度独立单位

    不同手机的像素密度不同,同px的元素可能有不同的物理尺寸,这不利于多屏幕的适配。因此Android以160dpi(每英寸160像素)为基准定义了单位dp。

    即1dp的元素在160dpi的屏幕用1个像素点px显示,在320dpi的屏幕用2px显示,但它们的显示实际物理长度均为1/160=0.00625英寸。320dpi在同样大小的屏幕内用了更多的像素显示,所以显得更「清晰」。

    hdpi、xhdpi、xxhdpi

    为了方便换算和显示,Android预定义了一系列的dpi作为基准,例如mdpi定义为160dpi、hdpi定义为240dpi(实际上是一定的范围,但不影响理解)。

    我们拿到的图片资源文件是以像素px为单位的,图标的显示却是以dp为单位的。在使用ImageView进行显示时,在规定好图标的长宽后其内容会自动缩放(不同的ScaleType缩放的逻辑不一样),像素过低的图标会显得「不清晰」。

    适用于高dpi屏幕的图标可以包含大量细节,在低dpi时直接缩放的话效果可能会出现锯齿、模糊或无法识别其中的元素等情况。为了分别针对不同显示密度的屏幕进行优化,Android在drawable和mipmap文件夹内为不同dpi的屏幕建立了不同的文件夹,在不同的设备上读取相应dpi文件夹内的图片资源进行显示。

    Toolbar的icon显示逻辑

    与ImageView这样的控件相比,Toolbar显示icon的逻辑就显得比较简单粗暴。在Material Design中,Toolbar的推荐高度为56dp,其中icon的尺寸建议为24dp,那么icon在不同dpi下的实际像素尺寸如下:

    ldpi 120dpi 0.75 18px
    mdpi 160dpi 1 24px
    hdpi 240dpi 1.5 36px
    xhdpi 320dpi 2 48px
    xxhdpi 480dpi 3 72px
    xxxhdpi 640dpi 4 96px

    这里的问题在于,Toolbar的MenuView在显示时读取图片资源后,不会检查是否应该缩放,而是直接居中显示。那么,如果你的图片资源经过屏幕像素密度换算后不是「恰好」24dp的话,最后显示的效果就会与期望的效果不一致。

    例如,xhdpi文件夹存放的应该是48px的icon,如果放入了96px大小的icon的话在Toolbar上就会显得2倍大。反之,在xxxhdpi中放入48px的icon看上去就会额外小。这也是为什么MD图标库中的icon会给mdpi到xxxhdpi一套图标的原因。

    解决方案

    通常情况下Toolbar的icon都是纯色的png图片,体积非常小。以ic_search_white_24dp.png这个图标为例,mdpi文件夹内的图片大小为396字节,而xxxhdpi文件夹内的图片大小也只有915字节,即使全部使用最大尺寸的图标,对安装包体积的影响也微乎其微。

    而且Toolbar的icon都是抽象的图标、细节不多,在低dip的设备上进行缩放时效果并没有太大差别,根据Google发布的设备屏幕尺寸分布情况,hdpi以上的设备也已经占了85%以上。所以如果想要减小安装包体积的话,Toolbar的icon是可以全部只使用一份96px*96px的图片资源,并存放在xxxhdpi中的。

    至于其他只在ImageView等控件中显示的资源,如果只有一份的话,放在哪个文件夹内其实是无所谓的。

    图标设计规范

    根据Material Design的设计规范,Toolbar icon的尺寸应为24dp,触摸响应大小为48dp(Toolbar会自动进行设置),而在icon内部应有一定的留白,一般为2-4dp。因此对于一张96px的icon来说,图片内的四周应有12px左右的边距。

    这里推荐一个神器 iconmonstr,在搜索框输入关键词找到想要的icon后,选择png、调整大小为96px、边距12px后,就可以直接下载了。

  • 相关阅读:
    一加5安卓P刷入twrp的recovery
    使用flask搭建微信公众号:实现签到功能
    使用flask搭建微信公众号:接收与回复消息
    Python中的单例设计模式
    Python中的异常处理
    Python面向对象 --- 新旧式类、私有方法、类属性和类方法、静态方法
    Python面向对象的三大特征 --- 封装、继承、多态
    Python面向对象 --- 类的设计和常见的内置方法
    Python中函数装饰器及练习
    Python中函数练习
  • 原文地址:https://www.cnblogs.com/endv/p/11312866.html
Copyright © 2011-2022 走看看