android识别全面屏的一种方法

3,060 阅读1分钟

面对现在越来越多全面屏手机,做业务时往往会遇到产品针对全面屏手机需要做一些特殊的处理。主要是通过通过分析window底部窗口区域,筛选出导航栏,监听虚拟导航栏的显示或者隐藏。

首先是自定义一个listener,主要是监测导航栏是否显示,以及导航栏的高度值

interface OnNavigationStateListener {

    /**
     * @param isShowing  导航栏是否显示
     * @param val 导航栏的高度值
     * */
    void onNavigationState(boolean isShowing,int val);
}

然后分析该window下底部是否存在导航栏高度,为true就认定导航栏存在。当然你也可以针对不同需求,设定不同的阀值进行判断。

 /**
     * 通过分析window底部窗口区域,筛选出导航栏,监听虚拟导航栏的显示或者隐藏
     */
    public static void isNavigationBarExist(final Window window, final OnNavigationStateListener onNavigationStateListener) {
        if (window == null || window.getContext() == null) {
            return ;
        }
        /** 获取导航栏高度*/
        final int height = getNavigationHeight()

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
            window.getDecorView().requestApplyInsets();
            window.getDecorView().setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
                @Override
                public WindowInsets onApplyWindowInsets(View v, WindowInsets windowInsets) {
                    int b = 0;
                    boolean isShowing = true;
                    // 判断Android当前的屏幕是横屏还是竖屏。横竖屏判断
                    if (window.getContext().getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
                        //竖屏
                        if (windowInsets != null) {
                            try {
                                b = windowInsets.getSystemWindowInsetBottom();
                            } catch (Exception e) {

                            }
                            isShowing = (b >= height);
                        }
                    }
                    if (onNavigationStateListener != null) {
                        onNavigationStateListener.onNavigationState(isShowing, b);
                    }
                    return v.onApplyWindowInsets(windowInsets);
                }
            });
        }
    }

在应用该方法判断过程当中,也遇到一些问题。 通过源码发现在设置OnApplyWindowInsetsListener,之后,如果不自定义实现方法,而是使用默认的window dispatch机制,return时调用v.onApplyWindowInsets(windowInsets);

其次在部分手机型号上面发现在设置setOnApplyWindowInsetsListener之前可能会存在已经消费过onApplyWindowInsets事件,而导致监听不起作用。所以在设置listener之前,requestApplyInsets()一下。

参考链接: Android全面屏虚拟导航栏适配