面对现在越来越多全面屏手机,做业务时往往会遇到产品针对全面屏手机需要做一些特殊的处理。主要是通过通过分析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全面屏虚拟导航栏适配