关键概念
屏幕密度
getResources().getDisplayMetrics().density;
屏幕像素密度
getResources().getDisplayMetrics().densityDpi;
屏幕分辨率, 比如1280*800
资源文件夹后缀,比如 hdpi xhdpi xxhdpi
为什么要适配
因为Android平台希望应用在不同的设备上表现一致。
具体点就是一个view如果在一个设备上的长是3cm(肉眼感知的物理长度),那么在其他设备上也是3cm左右。
这个主要是界面大小适配
图片为什么要适配?
因为一个ImageView虽然是3cm长,但是在不同的设备上,实际占据的分辨率不一样,比如一个100px 一个300px,此时如果我们用的是100px长的图片,在100px的设备没问题,但是在300px的设备上图片就虚了
Android平台提供什么样的机制来适配呢
屏幕像素密度densityDpi这个是每英寸像素点个数,一英寸是2.54cm,即物理尺寸上的像素个数,
假设A设备densityDpi=160,B设备densityDpi=240
如果想在两个设备上展示相同物理长度的view(即对两个设备适配),比如一英寸,则A设备需要设置view长为160px,B设备需要设置长为240px,这样代码就不好写了,
为此Android平台抽象了一个长度单位dp(也可以写作dip,两者是同一个意思),
并声明densityDpi=160时,1dp=1px,densityDpi=240时,1dp=1.5px,定义像素与dp的比值为屏幕密度density,
此时A设备可以设置view长为160dp 物理长度为1英寸,实际像素为160px,B设备也可以设置view长为160dp 物理长度1英寸,实际像素240px。
设置相同长度的dp,由于设备屏幕密度的不同,实际表现的物理长度相同,这样适配工作就好做了。
densityDpi=160时 1dp=1px density=1 资源文件夹后缀 mdpi
densityDpi=240时 1dp=1.5px density=1.5 资源文件夹后缀 hdpi
densityDpi=320时 1dp=2px density=2 资源文件夹后缀 xhdpi
densityDpi=480时 1dp=3px density=3 资源文件夹后缀 xxhdpi
等等
但是现实情况是每种设备的物理尺寸和屏幕分辨率并不标准,导致densityDpi可能并一定是160 240 320......
这种情况下一般Android系统会选择一个接近的屏幕密度,即densityDpi=180时 density还是1
这样在适配的时候,长度单位用dp,资源文件就可以按照屏幕密度给设备归类成 mdpi hdpi xhdpi等等情况
细节
系统在选取资源文件时,会选取最佳匹配,比如A B C设备本来用的默认配置,但是发现A需要适配,此时针对A适配,如果B C设备上系统判断A的配置最佳,B C也会选择A的适配资源,导致问题
系统选取了图片资源文件之后,会根据选取的配置和设备的配置进行缩放,放错目录就可能会出现虚的情况