前言
在这篇文章中也许可以看到一些在其他地方没有没看到过的知识点,这里会讲一些简要的适配应该知道的重要知识点,例如dp与px的换算,以及它们对内存性能的影响,另外现在很多公司使用了一些类似”蓝湖”类的可以自动生成dp值的网站,不需要我们程序员自己去计算dp值了,相当好用。
基础知识点:px、dpi、dp、sp
px : UI设计师的的设计图会以px作为统一的计量单位
px是Pixel的缩写,像素,它不是自然界中的长度单位,而是图片中最小的点,一张位图就是由这些最小的点组成,这里要注意,是位图的组成,除了位图还有矢量图,关于二者的区别可以自行去百度,我们说的手机分辨率,比如目前主流的1080p(1920*1080),就是竖向有1920个像素、横向1080个像素
dpi:Dots Per Inch 单位像素密度
一部手机的分辨率是宽x高,屏幕大小是以寸为单位,那么三者的关系是:
此处解释引用自:链接- dp、sp
dp、sp是谷歌给安卓开发的一套独有的屏幕适配长度单位,首先你要明白一点:这些单位他们最终的工作原理都是将这个长度按照一定的工作机制渲染成px,也就是像素。这篇文章主要想讲明白的就是渲染的计算方式。以dp为例,谷歌官网介绍是“与像素密度无关的单位”,但是官网同时又提出了以160dpi为基准,这看起来好像有些矛盾,既然是“无关”的,又提以dpi也就是像素密度作为基准,虽然官网没在具体的词条下面做出介绍,但是也不难理解,首先这个基准是什么意思呢? 基准就是标准单位,也就是在这个160dpi的基准下1dp就等以1px,以480*320分辨率,3.6英寸的手机来说,根据上面我们提到的像素密度计算方式可以得到这款手机的像素密度是160dpi,那么填满手机屏幕的宽度需要多少dp呢?因为宽度是320px,而这个基准下1dp=1px,那么宽度设置320dp就可以填满屏幕了。再看几个情况,也就是我们项目中默认的五个图片资源文件夹,mdpi、hdpi、xhdpi、xxhdpi、xxxhdpi他们分别对应的标准分辨率和像素密度是:(480*320、160dpi)、(800*480、240dpi)、(1280*720、320dpi)、(1920*1080、480dpi)、(2560*1440、640dpi),这几个都是最常见的情况,那么这几种分辨率下的dp和px是怎么换算的呢?只需要看这几种情况下的dpi大小与基准160之间的关系就可以了,比如240dpi,240/160=1.5,那么1dp就等于1.5px,320dpi情况下就是1dp=2px,这就是基准的作用,首先要得到像素密度,再看与基准dpi的关系,就可以得到dp与px之间的关系,然后“无关”怎么理解呢?安卓手机的屏幕大小分辨率组合太多了,不肯能计算出来的每个dpi都恰好等于上面那几个举例,比如现在最常见的(1920*1080、5.5英寸)的手机,实际计算出来的像素密度是400左右,如果按照上面的计算方式的话,400/160=2.5,那么填满屏幕宽度就需要1080/2.5=432dp,如果动手试一下,你会发现,确实填满了,再验证一下,把宽度设置为400dp,你会发现,依然可以填满,这就说明这种计算方式有些问题,问题在哪呢?dp是以像素密度范围进行寻址,而且是向上寻址意思就是(320dpi-480dpi】范围内按照480dpi来计算,也就是说,真正恰好填满(1920*1080、5.5英寸)这个参数的手机正确的dp值应该是1080/3=360dp,少一分则瘦,多一份则肥。
dp就介绍这些,sp和dp类似,正常的手机上也是和dp一样的,但是不同的是sp是设置字体大小的,我们知道手机系统可以调节手机上的字体大小,比如那些老人模式,如果用dp去设置字体大小,那就不能跟随系统字体大小去调节了,这些基础知识请一定牢记理解!在以后在开发中会有大作用,但是国内系统的定制程度较高有些手机把出厂的默认基准调高了,比如锤子手机,一样的屏幕大小和像素密度,锤子手机就会明显更大一些,另外设置字体大小的时候官方建议采用偶数:12sp、14sp、16sp,有助于提升性能。
实际开发
进入公司,首先我们要知道,公司UI是按照什么标准给你切图的,按照什么标准给你标注的,有时,公司内的美工切图只有一套,也就是按照ios的1334*750的像素、4.7的屏幕大小标准进行切图和标注,UI通常称这种图为二倍图,图片命名的时候后缀都是:@2x、@3x,这个后缀是Ios用来寻址图片的标志位,4.7deiphon8就会用@2x的图,5.5的iPhone8 Plus就会采用相同命名的@3X图,也就是他们说的三倍图,了解了上面的dp、sp的计算,相信这部分处理起来就容易了,2倍图要放到xhdpi里面,可别一听到二倍图或者看到一个@2x就放倒了xxhdpi里面,因为在安卓中的xxhdpi代表的是480dpi也就是UI说的三倍图了,看到标注计算的时候用二倍图除以2就可以得到合适的dp值了,当然了如果公司的UI比较给力,直接给你标出了dp值或者按照720p(1080*720)、或者1080p(1920*1080)的标准安卓常用分辨率来标注的话,那就直接使用就好了
最后的重点
安卓中图片放置在前边说过了dp是以像素密度进行寻址,图片的选择也是以范围寻址,比如一个有两个文件名相同的图片A和B,其中A放在xhdpi的mipmap文件夹中,B放在xxxhdpi的mipmap文件夹中,xxhdpi的mipmap文件夹不放图,那么1920*1080的手机会显示哪一张呢?和dp一样,也是向上寻址,最终会显示大分辨率的文件图片,如果当前的和大的都没有就会向下找最大的那个有图的,直到找到为止。需要注意,图片放置和dp值计算的所谓范围寻址,向上寻址,是不同的参考对象,dp值是以不同的设备为例,放置显示图片是在同一台设备上,这最后的重点就是放置图片可能造成的内存溢出问题,安卓中并不需要每一套文件夹中都放一套图,因为可以向上寻找其它分辨率文件中的图片,一些固定大小的图片可以通过设置显示scaleType来显示在多个分辨率和大小的手机上,一些设置包裹内容的图片则需要根据实际显示效果来确定是否在不同分辨率的文件夹中放置不同图片,但是需要注意如果放置错了图片位置就有可能造成内存溢出,比如我们将一个1.27M大小的图片放置到不同分辨率的mipmap文件夹中,然后分别运行到一款1080p的手机上,通过monitors查看app占用的内存,可以发现以下数据:
mdpi : 72M
hdpi : 32.88M
xhdpi : 19.05M
xxhdpi : 9.48M(最优)
可以看出来了吧,一张图片只有放置在正确的图片位置才能内存占用最优,因为越小分辨率的文件夹,系统在显示到高分辨率的手机上来的时候需要先进行放大到同等分辨率,所以就导致了mdpi的mipmap文件夹一个1.27M的图片占用内存72M之多,这样就极有可能造成内存溢出了,正确的做法切一套目前主流分辨率的图片,目前就是1920*1080占比最高,你会问,那2K的手机显示的时候把1080的放大也会导致占用内存过大啊,为什么不放在2K的文件夹也就是xxxhdpi中呢,首先,目前市面上主流就是1080,其次,分辨率高的手机往往意味着配置更高,系统分配给每个app内存更多,一张相同内容的图片切成不同分辨率的大小图片本身的大小也是不一样的,可能一张1080的图片本身2M,弄成2K的分辨率,图片本身就要8M了,这样占用的内存和2M小图放大后的并不会差多少。
如果反过来,将一个xxxxhdpi的图片显示到1080手机上什么效果呢?这里不贴过,只说一下结果:内存占用依然会比放在xxhdpi的文件夹中变大,只是不如xhdpi那么明显,另外最主要的影响是图片质量会下降,因为系统将大图进行压缩。
结尾推荐一款Studio插件:Android Wifi ADB
可以不用数据线链接电脑,安装重启后Studio控制面板右上方就会出来一个Android Wifi ADB的选项,首先要用线插一次,打开Android Wifi ADB这个控制面板,选择设备点一下connect,等state变成connected之后就可以把线拔掉了。这时候就可以无线运行程序了,如果嫌弃线材臃肿,又或者手机快没电了还要运行程序主机的充电不够快时,就可以一边用快速充电器充电,一边运行代码了。