navigationbar展示位置的获取

概述:

之前项目中曾经做过一个功能,需要根据在页面顶部靠边的位置添加一个菜单按钮,按钮点击后弹出popwindow,如果设备显示导航栏navigationbar,当导航栏显示在底部的时候,菜单键显示在页面左上角,当导航栏不在底部,而是在左右两侧的时候,菜单键总是显示在导航栏的对侧。

解决思路:

当进入页面的是,需要在页面的oncreate中根据导航栏的位置来设置菜单键的位置,经过查找,好像没有开放API可以返回导航栏的位置,网络搜索,也没有找到相关的信息,只剩下最后一个方法,去源码里头找找看看有没有类似的实现。查找思路如下:

  1. 在/framework/base/core/res/values文件夹中搜索navigation字符
  2. 如果步骤1搜索到了一些可能有用的信息,则根据步骤1搜索得到的可能信息去java代码中搜索
  3. 如果步骤1中没有没有得到可能有用的信息,则根据经验去systemui文件夹下或者几个跟窗口管理较密切的类中去查找,比如:windowmanagerservice,PhoneWindowManager等中去继续查找相关字符
实现过程:

1.在values文件夹中搜索navigation字符,得到的信息较多,需要自己去一个个筛选哪些信息可能会有用,这里发现很多都是导航栏高度、和颜色设置,这里发现一个是否显示导航栏的设置,在config.xml中:

    
    false

2.觉得这个设置可能引出我需要的信息,所以继续在java代码中去查找:
首先在framework/base/core/java/路径下查找config_showNavigationBar,结果没有找到任何相关引用的。
然后继续在frameworks/base/services/core/java目录下查找,结果在PhoneWindowManager类中找到了相关的引用:

mHasNavigationBar = res.getBoolean(com.android.internal.R.bool.config_showNavigationBar);

继续根据这个变量进行查找,发现该类中针对导航栏的方法较多,但是还是没有找到我们需要的信息,更换搜索词,扩大搜索范围,搜索navigation,最终发现有如下隐藏方法:

    private int navigationBarPosition(int displayWidth, int displayHeight, int displayRotation) {
        if (mNavigationBarCanMove && displayWidth > displayHeight) {
            if (displayRotation == Surface.ROTATION_270) {
                return NAV_BAR_LEFT;
            } else {
                return NAV_BAR_RIGHT;
            }
        }
        return NAV_BAR_BOTTOM;
    }

至此,我们就已经得到了我们所需要的全部信息了,方法虽然是hide方法,但是实现较为简单,我们可以将其实现方法直接拿出来使用即可,经过修饰与兼容android不同版本之后得出如下方法:

    public static boolean checkDeviceHasNavigationBar(Context context) {
        boolean hasNavigationBar = false;
        Resources rs = context.getResources();
        int id = rs.getIdentifier("config_showNavigationBar", "bool", "android");
        if (id > 0) {
            hasNavigationBar = rs.getBoolean(id);
        }
        return hasNavigationBar;
    }

    /** 8.0及以下系统获取导航栏显示位置
     *  返回导航栏位置,1是显示在底部,2是显示在右侧,0是不显示
     * @param cn
     * @return
     */
    public static int getNavPosO(Context cn) {
        WindowManager wmg = (WindowManager)cn.getSystemService(Context.WINDOW_SERVICE);
        final Display display = wmg.getDefaultDisplay();
        DisplayMetrics metricsReal = new DisplayMetrics();
        display.getRealMetrics(metricsReal);

        DisplayMetrics metricsCurrent = new DisplayMetrics();
        wmg.getDefaultDisplay().getMetrics(metricsCurrent);

        int currH = metricsCurrent.heightPixels;
        int currW = metricsCurrent.widthPixels;

        int realW = metricsReal.widthPixels;
        int realH = metricsReal.heightPixels;

        if(currH != realH && currW == realW) {
            return 1;
        } else if(currW != realW && currH == realH) {
            return 2;
        } else {
            return 0;
        }

    }

    /**9.0获取导航栏显示位置,1左边,2右边,4底部
     *
     * @param context
     * @return
     */
    public static int getNavPosP(Context context) {
        WindowManager wmg = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
        int pos = 0;
        Display display = wmg.getDefaultDisplay();
        int rotate = display.getRotation();
        int height = display.getHeight();
        int width = display.getWidth();
        if (width > height) {
            if (rotate == Surface.ROTATION_270) {
                pos =  1; //left
            } else {
                pos = 2; //right
            }
        } else {
            pos = 4; //bottom
        }
        return pos;
    }

你可能感兴趣的:(代码记录)