一、前言
底部NavigationBar经常会挡住界面,有时候NavigationBar出来界面会自动resize在他的上面, 有时候却被它挡在下面,今天来看一下具体的解决方案
二、适配
1、判断手机是否有NavigationBar
private 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);
}
try {
Class systemPropertiesClass = Class.forName("android.os.SystemProperties");
Method m = systemPropertiesClass.getMethod("get", String.class);
String navBarOverride = (String) m.invoke(systemPropertiesClass, "qemu.hw.mainkeys");
if ("1".equals(navBarOverride)) {
hasNavigationBar = false;
} else if ("0".equals(navBarOverride)) {
hasNavigationBar = true;
}
} catch (Exception e) {
Log.w(TAG, e);
}
return hasNavigationBar;
}
2、设置界面自动resize, 不被NavigationBar挡住
View decorView;
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
decorView = getWindow().getDecorView();
}
@Override
protected void onStart() {
super.onStart();
if (Build.VERSION.SDK_INT < 19 || !checkDeviceHasNavigationBar(this)) {
return;
} else {
// 主要就是通过设置特定的属性,来控制Navigationbar的显示,有兴趣的同学可以去查查相关介绍
int flag = (View.SYSTEM_UI_FLAG_VISIBLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
decorView.setSystemUiVisibility(flag);
}
}
3、字段讲解
在这个列表中,有几个需要注意的地方:
在某些手机上隐藏状态栏的标志SYSTEM_UI_FLAG_FULLSCREEN会失效,因为我用华为、Nexus和小米分别设置了这个标志,发现只有小米的设置才起作用,其它两类手机当隐藏掉状态栏时状态栏的位置会显示白条,APP的内容不会顶上去,如果有知道原因的同学麻烦告知下。因此,当需要隐藏掉状态栏时,推荐使用以下代码进行设置,或者结合SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN来设置:
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN)
在设置隐藏虚拟导航栏的标志的时候,如果结合
SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION可保持原来的布局,如果结合SYSTEM_UI_FLAG_IMMERSIVE触摸屏幕不会弹出虚拟导航栏
SYSTEM_UI_FLAG_IMMERSIVE和SYSTEM_UI_FLAG_IMMERSIVE_STIKY
需要结合SYSTEM_UI_FLAG_FULLSCREEN或者SYSTEM_UI_FLAG_HIDE_NAVIGATION一起使用,才能得到列表中展示的效果
SYSTEM_UI_FLAG_LAYOUT_STABLE没发现具体的效果,如果仅仅是为了保持布局,那么
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN和SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION也可以做到
另外,我们经常用到的fitSystemWindows只有在设置了半透明状态栏或者半透明虚拟导航栏中才有意义,它的作用是为你的APP腾出空间,将界面展示在状态栏下方和虚拟导航栏上方,从而不被状态栏和虚拟导航栏遮挡