1. 程式人生 > >android 螢幕寬高那點事

android 螢幕寬高那點事

 

目錄

寬高的獲取方式

導航欄的高度獲取及導航欄監聽


寬高的獲取方式

    1. 

 DisplayMetrics displayMetrics = new DisplayMetrics();
 getWindowManager().getDefaultDisplay().getRealMetrics(displayMetrics);
 int height = displayMetrics.heightPixels;

  2. 

 DisplayMetrics displayMetrics = new DisplayMetrics();
 getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
 return displayMetrics.heightPixels;

  3. 

 

this.getWindowManager().getDefaultDisplay().getHeight());

4. 

        Display display = getWindowManager().getDefaultDisplay();
        DisplayMetrics displayMetrics = new DisplayMetrics();
        Class c;
        try {
            c = Class.forName("android.view.Display");
            Method method = c.getMethod("getRealMetrics",DisplayMetrics.class);
            method.invoke(display, displayMetrics);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return displayMetrics.heightPixels;

 

獲取螢幕引數無非就是這幾種方式,現在歸納一下他們的區別。前三種方式利用系統的api,其都是差不多的,第四種是利用反射獲取的,但也是利用DisplayMetrics 類實現的。重點關注不在這裡,是他們獲取的值的不同對於含有虛擬導航欄的手機,如華為眾多型號的手機,這裡就不一樣了。第一,第四的值是螢幕的絕對高度,包含虛擬導航欄,而二三種方式獲取的是螢幕頂端到虛擬導航欄之間的高度,如果虛擬導航欄隱藏了,則四種方式獲取的高度相同,這裡是一個小小的點可以關注一下。


導航欄的高度獲取及導航欄監聽

看了上面的分析,自然可以知道獲取導航欄的高度可以利用高度差相減,在加上網友也分享的一種利用系統的api,下面兩種方法解析:

1. 高度差相減:見上面分析,但是有缺點就是不能保證第二三種方法獲取的高度是有虛擬導航欄的情況,有可能使用者把導航欄隱藏了;

2. 第二種方式:

private int getNavigationBarHeight(){
        int result = 0;
        if (hasNavBar()){
            Resources res = getResources();
            int resoureceId = res.getIdentifier("navigation_bar_height", "dimen", "android");
            if (resoureceId > 0 ){
                result = res.getDimensionPixelSize(resoureceId);
            }
        }
        return  result;
    }

    private boolean hasNavBar(){
        Resources res = getResources();
        int resoureceId = res.getIdentifier("config_showNavigationBar", "bool", "android");
        if (resoureceId != 0){
            boolean hasNav = res.getBoolean(resoureceId);
            String navBarOverride = getNavBarOverride();
            if ("1".equals(navBarOverride)){
                hasNav = false;
            }else if ("0".equals(navBarOverride)){
                hasNav = true;
            }
            return hasNav;
        }
        return !ViewConfiguration.get(this).hasPermanentMenuKey();

    }

    private String getNavBarOverride(){
        String sNavBarOverride = "";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
            try {
                Class c = Class.forName("android.os.SystemProperties");
                Method method = c.getDeclaredMethod("get", String.class);
                method.setAccessible(true);
                sNavBarOverride = (String) method.invoke(null, "qemu.hw.mainkeys");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
        return sNavBarOverride;
    }

關於虛擬導航欄的話題,比如適配,監聽虛擬導航的隱藏顯示。可以搜尋:Android 虛擬導航欄適配;對於監聽是不是也可以用viewTreeObserver 來實現了,也是一個方向,先記錄之,後面在驗證