px、dp、dpi之间的联系与转换
我们在设计界面难免要考虑视图的尺寸。 layout中我们经常用dp、pt指定控件的宽高,也有用到sp设置字体大小的。 自定义View的时候,我们绘制的图形经常用到px这个单位。
那么这些单位之间的区别与联系是什么,又如何相互转换呢
-
px:像素点。平常所说的1920×1080只是像素数量,也就是1920px×1080px,代表手机高度上有1920个像素点,宽度上有1080个像素点。 dpi:每英寸像素个数 dp:其实dp就是为了使得开发者设置的长度能够根据不同屏幕(分辨率/尺寸也就是dpi)获得不同的像素(px)数量。 比如:定义160dpi分辨率的手机上,1dp = 1px 那么560dpi分辨率的手机上, 1dp != 1px 而 = 560/160 * 1dp = 3.5px
也就是dp会随着不同屏幕而改变控件长度的像素数量。
那么需要获取屏幕分辨率信息:
Log.i("test draw","density:"+ getResources().getDisplayMetrics().density); Log.i("test draw","density dpi:"+ getResources().getDisplayMetrics().densityDpi);
得到
查看一个视图的大小:
<com.dream.drawcanvas.myView.CanvasDrawView android:layout_width="match_parent" android:layout_height="100dp" />
自定义View
public class CanvasDrawView extends View { public CanvasDrawView(Context context) { super(context); } public CanvasDrawView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } public CanvasDrawView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public CanvasDrawView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.DKGRAY); Log.i("test draw", "canvas.getwidth: "+ canvas.getWidth()+ " canvas.getHeight: "+ canvas.getHeight()); } }
结果:100dp 得到 350px 很明显 因为我们获取的 density dpi = 560, density = 3.5 = 560/160 所以 100dp在560dpi的屏幕上就等于350px个像素
canvas.getwidth: 1440 canvas.getHeight: 350
Android自带api方法:TypedValue.applyDimension()
TypedValue.applyDimension(int unit, float value, DisplayMetrics metrics)
// 获得转换后的px值 float pxDimension = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 16,context.getResources().getDisplayMetrics());
applyDimension 源码
public static float applyDimension(int unit, float value, DisplayMetrics metrics) { switch (unit) { case COMPLEX_UNIT_PX: // 转换为px(像素)值 return value; case COMPLEX_UNIT_DIP: // 转换为dp(密度)值 return value * metrics.density; case COMPLEX_UNIT_SP: // 转换为sp(与刻度无关的像素)值 return value * metrics.scaledDensity; case COMPLEX_UNIT_PT: // 转换为pt(磅)值 return value * metrics.xdpi * (1.0f / 72); case COMPLEX_UNIT_IN: // 转换为in(英寸)值 return value * metrics.xdpi; case COMPLEX_UNIT_MM: // 转换为mm(毫米)值 return value * metrics.xdpi * (1.0f / 25.4f); } return 0; }