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 来实现了,也是一个方向,先记录之,后面在验证

猜你喜欢

转载自blog.csdn.net/sjh_389510506/article/details/83658675
今日推荐