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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章