android 判断虚拟导航栏是否在屏幕上显示,适用于Lolli
2018-09-30 本文已影响60人
HuZC
# 写在前面
找了两天的判断方法,都是通过屏幕真实高度和内容高度作对比来判断,但是我的内容是可以沉到导航栏最底部的啊,这样就判断不了了。最后自己从DecorView源码中找到了解:
/**
* 不用内容高度和屏幕真实高度作对比来判断。
* 这里只适用于21以后的版本,方法是从DecorView源码中来的,
* 测试了模拟器21版本,和我自己手机Android 8.1.0都是有效的
* api min is 21 version
* 0:statusbar is visible
* 1:navigation is visible
*
* @return statusbar, navigation是否可见
*/
public static boolean[] isSystemUiVisible(Window window) {
boolean[] result = new boolean[]{false, false};
if (window == null) {
return result;
}
WindowManager.LayoutParams attributes = window.getAttributes();
if (attributes != null) {
result[0] = (attributes.flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != WindowManager.LayoutParams.FLAG_FULLSCREEN;
//
ViewGroup decorView = (ViewGroup) window.getDecorView();
result[1] = (((attributes.systemUiVisibility | decorView.getWindowSystemUiVisibility()) &
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) && (attributes.flags & WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0;
}
//
Object decorViewObj = window.getDecorView();
Class<?> clazz = decorViewObj.getClass();
int mLastBottomInset = 0, mLastRightInset = 0, mLastLeftInset = 0;
try {
Field mLastBottomInsetField = clazz.getDeclaredField("mLastBottomInset");
mLastBottomInsetField.setAccessible(true);
mLastBottomInset = mLastBottomInsetField.getInt(decorViewObj);
} catch (Exception e) {
e.printStackTrace();
}
try {
Field mLastRightInsetField = clazz.getDeclaredField("mLastRightInset");
mLastRightInsetField.setAccessible(true);
mLastRightInset = mLastRightInsetField.getInt(decorViewObj);
} catch (Exception e) {
e.printStackTrace();
}
try {
Field mLastLeftInsetField = clazz.getDeclaredField("mLastLeftInset");
mLastLeftInsetField.setAccessible(true);
mLastLeftInset = mLastLeftInsetField.getInt(decorViewObj);
} catch (Exception e) {
e.printStackTrace();
}
boolean isNavBarToRightEdge = mLastBottomInset == 0 && mLastRightInset > 0;
int size = isNavBarToRightEdge ? mLastRightInset : (mLastBottomInset == 0 && mLastLeftInset > 0 ? mLastLeftInset : mLastBottomInset);
result[1] = result[1] && size > 0;
return result;
}
# 测试
测试了5.0 和 8.1.0 都是有效的,中间的版本没测,至于5.0之前的版本,正在找方法中。
有什么问题请联系我 [ 笑脸 ]