系统栏
系统栏包括顶部的状态栏和底部的导航栏
将状态栏调暗
View decorView = getActivity().getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_LOW_PROFILE;
decorView.setSystemUiVisibility(uiOptions);
这种调节方式可逆,只要对状态栏有任务的触摸,都会让它回到原来的样子;我们也可以使用代码的方式手动还原,如下代码:
View decorView = getActivity().getWindow().getDecorView();
decorView.setSystemUiVisibility(0);
顶部状态栏
在android4.1以上使用 setSystemUiVisibility() 方法控制状态栏
如下代码代码隐藏状态栏:
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
//一般不显示状态栏也不会显示操作栏
ActionBar actionBar = getActionBar();
if (actionBar != null)
actionBar.hide();
使用这种方法隐藏状态栏时只要界面失去焦点就会失效,想要再次隐藏就得再次调用;上述方式隐藏的状态栏的变化会影响到下面我们设计的界面,要想使我们设计的界面的大小不随其变化(将内容延伸到状态栏),可以使用以下flag:
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
decorView.setSystemUiVisibility(uiOptions);
//一般不显示状态栏也不是显示操作栏
ActionBar actionBar = getActionBar();
if (actionBar != null)
actionBar.hide();
使用这种方式同样只要界面失去焦点就会失效,想要再次隐藏就得再次调用;还会引发的一个问题就是当我们把内容延伸到了状态栏之后,状态栏显示出来时,我们的内容会被遮挡掉,而此时状态栏也不会再隐藏了,解决这个问题可以在我们的 xml 文件的根目录设置属性
android:fitsSystemWindows="true"
底部导航栏
隐藏导航栏,这种方式隐藏的导航栏只要点击屏幕任意位置,都是使隐藏失效
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
decorView.setSystemUiVisibility(uiOptions);
使内容延伸到导航栏:
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
decorView.setSystemUiVisibility(uiOptions);
全屏模式
1.向后倾斜模式。使用以下模式只要点击屏幕任意位置就会失效:
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
decorView.setSystemUiVisibility(uiOptions);
2.沉浸模式。必须屏幕两端滑动才会使全屏失效:
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
decorView.setSystemUiVisibility(uiOptions);
3.粘性沉浸模式。沉浸模式的升级版,从屏幕两端滑动使全屏失效,但是如果此时不对系统栏做其他的触摸事件的话,又会自动变成全屏模式,唯一的缺点是无法监听系统栏的显示与否(下面讲监听系统栏的显示与否)
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
decorView.setSystemUiVisibility(uiOptions);
监听页面的可见性
- onWindowFocusChanged 方法,只要设计区被遮住或者重新显示都会触发此回调:
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
//hasFocus 是否可见
}
2.监听系统栏的状态(粘性沉浸模式无法收到此回调):
View decorView = getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener
(new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
//此时系统栏是显示的
} else {
//此时系统栏是隐藏的
}
}
});
通过上文我们知道粘性沉浸模式可以让系统栏显示后自动隐藏,但是我们收不到显示和隐藏的回调,所以我们无法在系统栏的状态变化时响应其他操作。比如:我既想要自动隐藏状态栏又想监听其状态的变化,此时可以使用 向后倾斜模式 + 监听器 + Handler 完成:
private final Handler mHandler = new Handler();
public void setListener(View view) {
View decorView = getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener
(new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
//此时系统栏是显示的
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
//3秒后隐藏系统栏
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
decorView.setSystemUiVisibility(uiOptions);
}
},3000);
} else {
//此时系统栏是隐藏的
}
}
});
}