我們在設計界面難免要考慮視圖的尺寸。
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;
}