天天看點

Android螢幕各尺寸的擷取方法詳解

在開發中我們會遇到各種需要獲得螢幕參數的場景,當中也有不少坑,是以現在就記錄一下這些參數的擷取方式。以免再入坑。

實體螢幕寬高

一、底部沒有虛拟按鍵

這裡擷取到的寬高,就是你眼睛能看到的,螢幕亮着的地方的寬高。

/**
     * 擷取螢幕的寬
     *
     * @param context
     * @return
     */
    public static int getScreenWidth(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics dm = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(dm);
        return dm.widthPixels;
    }

    /**
     * 擷取螢幕的高度
     *
     * @param context
     * @return
     */
    public static int getScreenHeight(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics dm = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(dm);
        return dm.heightPixels;
    }      

二、底部有虛拟按鍵

華為手機底部都會有一個黑色的虛拟按鍵(NavigationBar),通過上面這個方式得到的螢幕高度是螢幕 真是高度-虛拟按鍵的高度 。是以有虛拟按鍵的情況擷取螢幕的高度就是另一種方法了。

public static int getRealHeight(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        int screenHeight = 0;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            DisplayMetrics dm = new DisplayMetrics();
            display.getRealMetrics(dm);
            screenHeight = dm.heightPixels;

            //或者也可以使用getRealSize方法
//            Point size = new Point();
//            display.getRealSize(size);
//            screenHeight = size.y;
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            try {
                screenHeight = (Integer) Display.class.getMethod("getRawHeight").invoke(display);
            } catch (Exception e) {
                DisplayMetrics dm = new DisplayMetrics();
                display.getMetrics(dm);
                screenHeight = dm.heightPixels;
            }
        }
        return screenHeight;
    }      

虛拟按鍵高度

虛拟按鍵(NavigationBar)高度可以通過讀取定義在Android系統尺寸資源中的 navigation_bar_height 獲得。

是以不管虛拟按鍵是顯示還是隐藏,得到的結果都是一樣的。

public static int getNavigationBarHeight(Context context) {
        int navigationBarHeight = -1;
        Resources resources = context.getResources();
        int resourceId = resources.getIdentifier("navigation_bar_height","dimen", "android");
        if (resourceId > 0) {
            navigationBarHeight = resources.getDimensionPixelSize(resourceId);
        }
        return navigationBarHeight;
    }      

狀态欄高度

狀态欄就是螢幕頂部顯示時間,電池,wifi 等資訊的欄目。

  1. 方法一:系統提供了一個Resource類,通過這個類可以擷取資源檔案,借此可以擷取 到status_bar_height 。
public int getStatusBarHeight() {
        int result = 0;
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }      
  1. 方法2: 通過放射

    Android的所有資源都會有惟一辨別在R類中作為引用。我們也可以通過反射擷取R類的執行個體域,然後找 status_bar_height。

public void getStatusBarHeightByReflect() {
        int statusBarHeight2 = -1;
        try {
            Class<?> clazz = Class.forName("com.android.internal.R$dimen");
            Object object = clazz.newInstance();
            int height = Integer.parseInt(clazz.getField("status_bar_height")
                    .get(object).toString());
            statusBarHeight2 = getResources().getDimensionPixelSize(height);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Log.e(TAG, "狀态欄高度-反射方式:" + statusBarHeight2);
    }      
  1. 借助應用區 top 屬性。

    狀态欄位于螢幕的最頂端,坐标從 (0,0) 開始,是以應用區的頂部的位置就是狀态欄的高度。

/**
     * 應用區的頂端位置即狀态欄的高度
     * *注意*該方法不能在初始化的時候用
     * */
    public void getStatusBarHeightByTop() {
        
        Rect rectangle = new Rect();
        getWindow().getDecorView().getWindowVisibleDisplayFrame(rectangle);
        Log.e(TAG, "狀态欄高度-應用區頂部:" + rectangle.top);
    }      

應用區域高度

除去狀态欄剩下的都時應用區。由此可知 螢幕的高度 - 狀态欄高度 = 應用區的高度 。

/**
     * 不能在 onCreate 方法中使用。
     * 因為這種方法依賴于WMS(視窗管理服務的回調)。正是因為視窗回調機制,是以在Activity初始化時執行此方法得到的高度是0。
     * 這個方法推薦在回調方法onWindowFocusChanged()中執行,才能得到預期結果。
     */
    public void getAppViewHeight(){
        //螢幕
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        //應用區域
        Rect outRect1 = new Rect();
        getWindow().getDecorView().getWindowVisibleDisplayFrame(outRect1);
        int statusBar = dm.heightPixels - outRect1.height();  //狀态欄高度=螢幕高度-應用區域高度
        Log.e(TAG, "應用區高度:" + statusBar);
    }      

setContentView 高度,view 顯示的高度

需要在見面建立後才能擷取到。

public static int getContentViewHeight(Activity activity) {
        Rect rectangle= new Rect();
        activity.getWindow().findViewById(Window.ID_ANDROID_CONTENT).getDrawingRect(rectangle);
        return rectangle.height();
    }      

标題欄高度

标題欄高度 = 應用區高度 - view 顯示高度

public static void getTitleBarHeight(Activity activity) {
        Rect outRect1 = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(outRect1);

        int viewTop = activity.getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();   //要用這種方法
        int titleBarH = viewTop - outRect1.top;

        Log.e(TAG, "标題欄高度-計算:" + titleBarH);
    }