1、将状态栏和导航栏变变暗
在Android 4.0(API 14)以及更高的版本中,提供了一些将状态栏和导航栏变暗的方法,低版本没有提供相应的方法。
代码如下:
// This example uses decor view, but you can use any visible view.
View decorView = getActivity().getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_LOW_PROFILE;
decorView.setSystemUiVisibility(uiOptions);
设置将状态栏和导航栏变暗之后,实际上还是能看到的,但是隐藏了一些细节,当点击状态栏或者导航栏的时候,这个flag就会被清除,你的app就需要重新设置这个flag
View decorView = getActivity().getWindow().getDecorView();
// Calling setSystemUiVisibility() with a value of 0 clears
// all flags.
decorView.setSystemUiVisibility(0);
2、隐藏StatusBar
隐藏状态栏可以让app的内容使用更多的空间,可以给人一种更加沉浸式的用户体验
图一:有状态栏的

图二:没有状态栏的:

注意:当statusbar被隐藏的时候,action bar也会被隐藏
在Android 4.0及以下系统中隐藏status bar
在4.0(API 14)及以下的版本中,你可以通过设置WindowManager flags来隐藏状态栏。你可以通过代码或者配置manifest文件中的activity的主题来实现。如果你的状态栏需要一直隐藏,最好使用在清单文件中配置activity的主题方式,当然了,你也 可以通过代码的方式来覆盖配置的主题,例如:
<application
...
android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen" >
...
</application>
通过配置配置activity主题的优势有:
1、更易维护,更少出错
2、它会导致更加平滑的过渡,因为系统会在实例化主activity之前渲染UI
或者,你可以通过编码的方式设置WindowManager flags,当用户与你的app交互的时候,这种方式更加容易
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// If the Android version is lower than Jellybean, use this call to hide
// the status bar.
if (Build.VERSION.SDK_INT < 16) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
setContentView(R.layout.activity_main);
}
...
}
当你通过WindowManager设置了flags,无论是配置清单文件还是通过代码方式,这个flags都会持续影响直到你清理这个flags.
You can use
FLAG_LAYOUT_IN_SCREEN
to set your activity layout to use the same screen area that's available when you've enabled
FLAG_FULLSCREEN
. This prevents your content from resizing when the status bar hides and shows.
在Android4.1及以上系统中隐藏status bar
在Android4.1(api 16)和更高的版本中使用
setSystemUiVisibility()
来隐藏状态栏,你可以在某个View级别上通过
setSystemUiVisibility()
来设置UI flags。这些设置会上升到window级别。使用
setSystemUiVisibility()
可以更好的控制状态栏和导航栏,相比通过WindowManager设置flags,代码如下:
View decorView = getWindow().getDecorView();
// Hide the status bar.
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
// Remember that you should never show the action bar if the
// status bar is hidden, so hide that too if necessary.
ActionBar actionBar = getActionBar();
actionBar.hide();
注意以下几点:
一旦UI flags被清理掉了(例如跳转到另外的app),你的app需要重新设置这些flags,查看
Responding to UI Visibility Changes
动态相应UI Visibility改变事件一文,这篇文章讨论了如何监听UI visibility的改变,以便在改变的同时让app的界面也做必要的改变
在不同的地方设置UI flags是有区别的,如果你是在onCreate()中设置的UI flags隐藏system bar,当用户点击home键,system bar就会重新出现,当用户重新回到这个activity的时候,onCreate()不会被调用,所以system bar仍然是可见的,因此如果你想切换回来的时候仍然保持system bar的状态,最好是在onResume()或者onWindowFocusChanged()方法中设置UI flag
只有当调用者的View是可见的时候,方法setSystemUIVisibility()才会有效
界面的切换会导致setSystemUiVisibility的设置被清空
让内容布局在status bar的后面
在4.1以及以后的版本,可以让activity的内容部分显示在status bar的后面,status bar不再影响实际空间的摆放,因此在status bar切换显示状态的时候,内容区域的大小就不会发生改变。
要达到这种效果只需使用SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN标志(flag)。同时,你也有可能需要SYSTEM_UI_FLAG_LAYOUT_STABLE这个标志来帮助你的应用维持一个稳定的布局。
在一些情况下,你可能需要修改默认的padding大小来获取合适的布局。为了控制内容区域的布局相对系统栏的位置,你可以重写fitSystemWindows(Rect insets)方法。当窗口的内容嵌入区域发生改变时,fitSystemWindows()方法会被view的hierarchy调用,让View做出相应的调整适应。重写这个方法你就可以按照你的意愿处理嵌入区域与应用的布局。
3、隐藏NavigationBar

隐藏 Navigation Bar 的实现
通过设置SYSTEM_UI_FLAG_HIDE_NAVIGATION来隐藏导航栏。下面的代码同时隐藏了状态栏和导航栏
View decorView = getWindow().getDecorView();
// Hide both the navigation bar and the status bar.
// SYSTEM_UI_FLAG_FULLSCREEN is only available on Android 4.1 and higher, but as
// a general rule, you should design your app to hide the status bar whenever you
// hide the navigation bar.
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
注意以下几点:
使用这种方式,触摸屏幕的任何地方都会造成导航栏和状态栏重新显示并保持可见。flags会被清除。
设置 UI flags 的时机不同会产生不同的效果。如果你在 activity的
onCreate()
方法中隐藏了system bars,然后用户按了Home键,system bars 会重新显示出来。当用户重新打开这个activity的时候,
onCreate()
不会再被调用了,所以system bars将保持可见状态。如果你想要在进出activity时保持system UI 的改变状态, 在
onResume()
或者
onWindowFocusChanged()
方法中设置UI flags。
只有当调用setSystemUiVisibility()的view可见的时候才起作用
切换页面的时候调用setSystemUiVisibility()设置的flags将会被清除
让内容布局在navigation bar的后面
在4.1或者更高的版本中,你可能需要将你的内容布局设置在导航栏的下面,同时内容布局不会随着navigation bar的显示隐藏改变尺寸。想要达到这个效果,你需要设置
SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
,你同样需要使用
SYSTEM_UI_FLAG_LAYOUT_STABLE
来让你的app保持一个稳定的布局。
4、全屏模式
Android提供了三种方式来让你的屏幕全屏:Lean Back、Immersive、Immersive Sticky。这三种方式都会隐藏System bars,并且你的activity将会继续接受各种触摸事件。区别是将System bars重新显示的方式不同。
Lean Back

当用户点击了屏幕屏幕的任何位置都会让System bars重新显示。可以通过调用setSystemUiVisibility()设置
SYSTEM_UI_FLAG_FULLSCREEN
and
SYSTEM_UI_FLAG_HIDE_NAVIGATION
.
Immersive


这种模式下,当用户从手机屏幕边缘滑动的时候,System bars才会显示。通过调用setSystemUiVisibility(),并设置
SYSTEM_UI_FLAG_IMMERSIVE
并结合
SYSTEM_UI_FLAG_FULLSCREEN
和
SYSTEM_UI_FLAG_HIDE_NAVIGATION
使用
Sticky Immersive
这种方式是从屏幕边缘滑动状态栏只会显示一个半透明的状态,如果用户没有交互或者点击了System bars以外的区域的时候,过一段时间这个透明状态就会消失。可以通过
setSystemUiVisibility()
设置
SYSTEM_UI_FLAG_IMMERSIVE_STICKY
、
SYSTEM_UI_FLAG_FULLSCREEN
、
SYSTEM_UI_FLAG_HIDE_NAVIGATION
.
这种模式下在系统UI显示变化时,不会收到回调
5、监听UI可见状态
为了监听系统UI的可见状态,你需要给你需要控制导航栏的View设置一个监听
View.OnSystemUiVisibilityChangeListener
,例如你可以将下面的代码添加到你的activity的onCreate()中:
View decorView = getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener
(new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
// Note that system bars will only be "visible" if none of the
// LOW_PROFILE, HIDE_NAVIGATION, or FULLSCREEN flags are set.
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
// TODO: The system bars are visible. Make any desired
// adjustments to your UI, such as showing the action bar or
// other navigational controls.
} else {
// TODO: The system bars are NOT visible. Make any desired
// adjustments to your UI, such as hiding the action bar or
// other navigational controls.
}
}
});