首页 > 代码库 > 设备适配以及dp、ppi、sp等相关概念图文理解
设备适配以及dp、ppi、sp等相关概念图文理解
1. dpi是dot per inch,每英寸多少点,ppi是 Pixel per inch,每英寸像素数,针对显示器的设计时,dpi=ppi。
而安卓代码中常用density(点密度)来表示。ppi的计算方式呢可以根据勾股定理以及小学数学知识就能算出了哈哈,
例如小米2s分辨率1280*720,4.3寸。
这样的话可以得到ppi=(√1280^2+720^2)/4.3=341.53...可以粗略估计为320ppi
2.dip或dp(device independent pixels)设备独立像素。是安卓开发中独有的单位,规定在160ppi的设备上将1px设为1dp。什么意思呢?
先看下面几张图
这是分别在三种不同设备上显示一张尺寸一样的图片效果,我们发现规律即ppi越低图片显示越大,因此要让不同设备显示相同大小的图片需要缩放图片。
这也就有了在开发工作中res资源分为几个目录分别是mdpi,hdpi,xhdpi,xxhdpi等。解决上述问题我们需要如下图所示
根据缩放比例我可以得到一个等比例公式即,px1/px2=ppi1/ppi2。
选定一个ppi值作为基础绘制图片,用ppi的比值计算出图片缩放比例就可以适配各种屏幕
px2=px1*(ppi2/ppi1)
安卓选定的这个基础值就是160ppi
px2=px1*(ppi2/160)
我们已经解决了图片放大缩小的问题,还需要一个单位用来描述长度(因为px不固定,inch不方便)。
安卓就创造了一个新的单位dp,中文名:设备独立像素。并且规定在160ppi的屏幕上,1dp=1px。
因此上述的公式就变成了
px=dp*(ppi/160)
3.sp安卓自定义单位来描述字体的大小,原理同dp一样。
对于sp与点密度之间的对应关系如下:
4.好了说了那么多概念应该用代码验证一下了。对于上述讲到的各个参数都可以通过DisplayMetrics类得到
public class ThirdActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); String strScreenDIP = ""; strScreenDIP += "The logical density of the display: " + dm.density + "\n"; strScreenDIP += "The screen density expressed as dots-per-inch: " + dm.densityDpi +"\n"; strScreenDIP += "The absolute height of the display in pixels: " + dm.heightPixels +"\n"; strScreenDIP += "The absolute width of the display in pixels: " + dm.widthPixels + "\n"; strScreenDIP += "A scaling factor for fonts displayed on the display: " + dm.scaledDensity + "\n"; strScreenDIP += "The exact physical pixels per inch of the screen in the X dimension: " + dm.xdpi + "\n"; strScreenDIP += "The exact physical pixels per inch of the screen in the Y dimension: " + dm.ydpi + "\n"; TextView textScreenDIP = (TextView)findViewById(R.id.text_view); textScreenDIP.setText(strScreenDIP); } }
可以看到三星屏幕分辨率很低。
设备/参数 | dm.density | dm.densityDpi(ppi) | dm.heightPixels dm.widthPixels | dm.scaledDensity | dm.xdpi | dm.ydpi |
小米2s | 2.0 | 320 | 1280*720 | 2.0 | 160.421 | 160157 |
N7 | 2.0 | 320 | 1824*1200 | 2.0 | 320.842 | 322.966 |
三星 | 1.0 | 160 | 800*1280 | 1.0 | 149.824 | 149.411 |
首先第一个参数dm.density代表逻辑的点密度(The logical density of the display)默认1.0的情况下DPI为160,同样参数dm.scaledDensity代表字体缩放因子(A scaling factor for fonts displayed on the display)故这两个参数和PPI以及android开发中的资源包命名存在如下对应:
dm.density | dm.scaledDensity | PPI | 资源命名 |
1.0x | 1.0x | 160 | mdpi |
1.5x | 1.5x | 240 | hdpi |
2.0x | 2.0x | 320 | xhdpi |
3.0x | 3.0x | 480 | xxhdpi |
4.0x | 4.0x | 640 | xxxhdpi |
因此根据上述对应我们在res/drawable-mdpi/下跟换了图片换成了如三星平板显示一样的图片,而在小米2s和nexus 7上没有更换因此与三星显示的效果就不一样了。
对于最后一组参数dm.xdpi和dm.ydpi是指准确的dpi(The exact physical pixels per inch of the screen in the X dimension.)对于小米2s的这组数据为什么不约等于dm.densityDpi我很困惑????在其他设备上(跟小米配置相似的如大神F1和魅族MX)最后一组参数都约等于densityDpi。随后我又换了一台小米2s,而这台2s最后一组数据约等于320,那么为什么我的小米手机2s最后一组数据确是160多呢(我的2s刷成了基于android4.4.4的miuiv6了)
再有一点就是根据屏幕的大小自定义适配,如下表展示:
android3.2以前: android3.2以后:
因为N7的dp约等于600(比600大点)。
设备适配以及dp、ppi、sp等相关概念图文理解