dp 密度 分辨率 屏幕 狀態欄 標題欄 適配

一篇總結的很是完善的博文: http://www.jianshu.com/p/ec5a1a30694b

屏幕像素參數相關信息表格

屏幕級別   像素密度  每英寸像素數   一般分辨率       分辨率別稱     默認圖標大小
    
    
    
    
xxhdpi       3           480       1080*1920       1080P        144*144       重點關注
xhdpi        2            320        720*1280         720P          96*96          適配基準
hdpi         1.5          240        480*800          WVGA        72*72  
mdpi        1.0          160        320*480          HVGA         48*48          基準
ldpi          0.75        120        240*320          QVGA         36*36
System.out.println(Math.sqrt(Math.pow(1920, 2) + Math.pow(1080, 2)) / 5);//440.58
System.out.println(Math.sqrt(Math.pow(1920, 2) + Math.pow(1080, 2)) / 5.5);//400.53
System.out.println(Math.sqrt(Math.pow(1920, 2) + Math.pow(1080, 2)) / 6.0);//367.15
 

主流Android手機分辨率

屏幕級別  倍數/比例    像素密度範圍      主流分辨率/寬高比   分辨率別稱    標準圖標大小
xxxhdpi        4            480-640         2560*1440/16:9       2K              192*192
                                                        3840*2160/16:9       4K
xxhdpi          3            320-480        1920*1080/16:9       1080P         144*144
xhdpi            2            240-320        1280*720/16:9         720P           96*96
                                                        960*540                   QHD
hdpi            1.5          160-240         800*480/5:3             WVGA         72*72
                                                        854*480/16:9           FWVGA
                                                        640*480/4:3             VGA
                                                        800*600/4:3             SVGA
mdpi          1.0          120-160         320*480                    HVGA         48*48
ldpi            0.75        120                 240*320                   QVGA         36*36

iPhone系列手機的分辨率

iPhone 3G/3GS          480 x 320
iPhone 4/4S                960 x 640
iPhone 5/5s/5c           1136 x 640
iPhone 6/6s/7             1334*750
iPhone 6p/6sp/7p       1920*1080

名詞解釋

名詞解釋
   
   
   
   
  • Px(像素Pixel)
    • px即像素,一個像素則代表在屏幕上的一個點,一個顯示單位。
    • 不一樣設備上顯示時像素數不會變,好比指定控件的長度是100px,那無論分辨率是多少控件長度都是100px。也正是由於如此才產生了屏幕適配問題。
  • Screen Size(屏幕的尺寸)
    通常所說的手機屏幕大小如5.0英寸,都是指的手機屏幕對角線的長度,而不是手機面積。
  • Resolution(屏幕的分辨率)
    • 在屏幕上顯示的物理像素總和,單位是px,1px=1個像素點。
    • 通常以縱向像素*橫向像素表示,好比分辨率是1280*720,則指設備垂直方向有1280個像素點,水平方向有720個像素點。
    • 須要注意的是:分辨率並不意味着具體的屏幕高寬比,好比分辨率爲1280*720的手機屏幕寬高比不必定是1280*720(16:9)。可是爲了顯示效果和諧,二者通常都是一致的(或者有一丟丟的差距)。
  • Dpi(像素密度dots per inch)
    • 即「dot per inch」的縮寫,指每英寸中的像素數。
    • 屏幕像素密度與屏幕尺寸和屏幕分辨率有關,在單一變化條件下,屏幕尺寸越小、分辨率越高,像素密度越大。
    • DisplayMetrics類中屬性density的值即爲此值,可用於px與dip的互相轉換
    • dp是一個與密度無關的像素,在不一樣的像素密度的設備上會自動適配,在邏輯尺寸上,與一個位於像素密度爲 160DPI 的屏幕上的像素是一致的,在運行的時候,平臺會以目標屏幕的密度做爲基準,處理全部須要的DIP縮放操做。假定設備分辨率爲320*240,屏幕長2英寸寬1.5英寸,dpi=320/2=240/1.5=160,此160dpi表示手機水平或垂直方向上每英寸距離有160個像素點。
  • Dip(設備獨立像素Device-independent pixel)
    • dp和dip是一個意思,翻譯爲設備獨立像素,或是密度無關像素
    • 在Android中,規定以160dpi爲基準,此時1dip=1px;若是像素密度是320dpi,則1dip=2px
    • 要把DIP像素轉換爲屏幕像素,能夠用這樣一個簡單的公式: pixels = dips * (density / 160)。
  • Sp(放大像素ScaledPixels)
    主要用於字體顯示(best for textsize)。根據 google 的建議,TextView 的字號最好使用 sp 作單位,並且查看TextView的源碼可知 Android 默認使用 sp 做爲字號單位。

屏幕適配方法

一、使用不一樣套圖適配
使用套圖適配目前來講是針對 圖片適配的最好適配方法,能夠 防止圖片的失真以及變形
但針對不一樣手機進行不一樣的套圖適配,會對UI人員施加過大的工做壓力以及對咱們app自己也會形成冗餘的影響。

二、9path適配
9path圖片做爲特殊的png圖片,能夠在特定的狀況下對不一樣機型進行適配,而達到圖片不失真的狀況。

三、佈局適配
使用權重適配。 在格局比較明朗的頁面中,若是咱們能少用具體大小dp值,多用權重,能夠在不一樣的分辨率下都能作到完美適配。
 
四、使用dimens適配
根據不一樣values下的dimens進行適配,android項目會自動找尋相適應的dimens,咱們能夠在多種不一樣的values下創建dimens文件。
在使用dimens的時候,咱們能夠在dimens文件中,用px爲單位,這樣就能達到完美適配。

五、代碼適配
咱們也能夠在java文件中,使用java代碼 並結合dimens進行適配,相比較xml的話,此種適配方法更迅捷。

Activity

public class MainActivity extends Activity {
    private TextView tv_info;
    public static final String FILE_PATH = Environment.getExternalStorageDirectory().getAbsolutePath();
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        tv_info = new TextView(this);
        setContentView(tv_info);
        tv_info.setText("" + DensityUtils.getStatusBarHeight(this));//狀態欄高度。奇酷72。華爲75
        tv_info.append("\n" + DensityUtils.getDisplayMetrics(this));//像素密度。奇酷2.875。華爲3.0
        tv_info.append("\n" + DensityUtils.dp2px(this, 10.3f));
        tv_info.append("\n" + DensityUtils.px2dp(this, 10.3f));
        tv_info.append("\n" + DensityUtils.sp2px(this, 10.3f));
        tv_info.append("\n" + DensityUtils.px2sp(this, 10.3f));
        tv_info.append("\n" + DensityUtils.getScreenWidth(this) + "-" + DensityUtils.getScreenWidth2(this));
        tv_info.append("\n屏幕高度:" + DensityUtils.getScreenHeight(this));//奇酷1920。華爲1794
        tv_info.append("\n狀態欄高度:" + DensityUtils.getStatusBarHeight(this));//奇酷72。華爲75
        //須要 root 權限,且可能會被360報毒
        //        DensityUtils.saveBitmap2Pic(DensityUtils.snapShotWithStatusBar(this), FILE_PATH + "1.png");
        //        DensityUtils.saveBitmap2Pic(DensityUtils.snapShotWithoutStatusBar(this), FILE_PATH + "2.png");
    }
    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            tv_info.append("\n標題欄高度:" + DensityUtils.getTitleBarHeight(this));//奇酷161。華爲168
        }
    }
}

演示效果

奇酷1080P    華爲1080P    華爲720P
狀態欄高度25dp*3=75    25dp*2=50    25dp*2.875=71.875
     

工具類

package com.bqt.pop;
import java.lang.reflect.Method;
import android.app.Activity;
import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Display;
import android.view.Window;
import android.view.WindowManager;
public class DensityUtils {
    //******************************************************************************************
    //                                                                                    單位轉換
    //******************************************************************************************
    /**像素密度*/
    public static float getDisplayMetrics(Context context) {
        return context.getResources().getDisplayMetrics().density;
    }
    /**  dp 轉成爲 px     */
    public static int dp2px(Context context, float dpValue) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue, context.getResources().getDisplayMetrics());
    }
    /**  px 轉成爲 dp     */
    public static int px2dp(Context context, float pxValue) {
        return (int) (pxValue / getDisplayMetrics(context) + 0.5f);
    }
    /** sp轉px */
    public static int sp2px(Context context, float spVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, spVal, context.getResources().getDisplayMetrics());
    }
    /** px轉sp */
    public static float px2sp(Context context, float pxVal) {
        return (pxVal / context.getResources().getDisplayMetrics().scaledDensity);
    }
    //******************************************************************************************
    //                                                                                屏幕寬高
    //******************************************************************************************
    /**  獲取屏幕寬  */
    public static int getScreenWidth(Context context) {
        DisplayMetrics metric = new DisplayMetrics();
        ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(metric);
        return metric.widthPixels;
    }
    /** 獲取屏幕高,包含狀態欄,但不包含某些手機最下面的【HOME鍵那一欄】,如1920屏幕只有1794  */
    public static int getScreenHeight(Context context) {
        DisplayMetrics metric = new DisplayMetrics();
        ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(metric);
        return metric.heightPixels;
    }
    /**  獲取屏幕寬  */
    public static int getScreenWidth2(Context context) {
        Point point = new Point();
        ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getSize(point);
        return point.x;
    }
    /**  獲取屏幕高,包含狀態欄,但不包含某些手機最下面的【HOME鍵那一欄】,如1920屏幕只有1794  */
    public static int getScreenHeight2(Context context) {
        Point point = new Point();
        ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getSize(point);
        return point.y;
    }
    /**  獲取屏幕原始尺寸高度,包括狀態欄以及虛擬功能鍵高度  */
    public static int getAllScreenHeight(Context context) {
        Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
        try {
            DisplayMetrics displayMetrics = new DisplayMetrics();
            Method method = Class.forName("android.view.Display").getMethod("getRealMetrics", DisplayMetrics.class);
            method.invoke(display, displayMetrics);
            return displayMetrics.heightPixels;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }
    //******************************************************************************************
    //                                                                        狀態欄、標題欄、虛擬按鍵
    //******************************************************************************************
    /** 狀態欄高度,單位px,通常爲25dp  */
    public static int getStatusBarHeight(Context context) {
        int height = 0;
        int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            height = context.getResources().getDimensionPixelSize(resourceId);
        }
        return height;
    }
    /** 狀態欄高度,單位px,【注意】要在onWindowFocusChanged中獲取才能夠 */
    public static int getStatusBarHeight2(Activity activity) {
        Rect rect = new Rect();
        //DecorView是Window中的最頂層view,能夠從DecorView獲取到程序顯示的區域,包括標題欄,但不包括狀態欄。因此狀態欄的高度即爲顯示區域的top座標值
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
        return rect.top;
    }
    /**標題欄的高度,【注意】要在onWindowFocusChanged中獲取才能夠*/
    public static int getTitleBarHeight(Activity activity) {
        int contentTop = activity.getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
        return contentTop - getStatusBarHeight(activity);
    }
    /**獲取 虛擬按鍵的高度     */
    public static int getBottomBarHeight(Context context) {
        return getAllScreenHeight(context) - getScreenHeight(context);
    }
}
2017-7-27


相關文章
相關標籤/搜索