本课程介绍了如何在不同版本的 Android 上隐藏状态栏。隐藏状态栏(以及可选的导航栏)可以让内容使用更多的显示空间,从而提供更具沉浸感的用户体验。
图 1 显示了状态栏可见的应用

图 1. 状态栏可见。
图 2 显示了状态栏隐藏的应用。请注意,操作栏也被隐藏了。在不显示状态栏的情况下,绝不应该显示操作栏。

图 2. 状态栏隐藏。
在 Android 4.0 及更低版本上隐藏状态栏
您可以通过设置 WindowManager
标志,在 Android 4.0(API 级别 14)及更低版本上隐藏状态栏。您可以通过编程方式实现,也可以通过在应用的清单文件中设置 Activity 主题实现。如果状态栏应始终在您的应用中保持隐藏,则首选在应用的清单文件中设置 Activity 主题(尽管严格来说,如果您愿意,也可以通过编程方式覆盖主题)。例如
<application ... android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen" > ... </application>
使用 Activity 主题的优势如下
- 与通过编程方式设置标志相比,它更容易维护,且不易出错。
- 它可以实现更流畅的 UI 过渡,因为系统在实例化应用的主 Activity 之前就已拥有渲染 UI 所需的信息。
或者,您也可以通过编程方式设置 WindowManager
标志。当用户与您的应用交互时,此方法可以更轻松地隐藏和显示状态栏
Kotlin
class MainActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { 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) { window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN) } setContentView(R.layout.activity_main) } ... }
Java
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
标志时(无论是通过 Activity 主题还是通过编程方式),这些标志会保持生效,除非您的应用将其清除。
您可以使用 FLAG_LAYOUT_IN_SCREEN
将 Activity 布局设置为使用与启用 FLAG_FULLSCREEN
时可用的屏幕区域相同的区域。这可以防止内容在状态栏隐藏和显示时调整大小。
在 Android 4.1 及更高版本上隐藏状态栏
您可以使用 setSystemUiVisibility()
在 Android 4.1(API 级别 16)及更高版本上隐藏状态栏。setSystemUiVisibility()
在单个视图级别设置 UI 标志;这些设置会聚合到窗口级别。与使用 WindowManager
标志相比,使用 setSystemUiVisibility()
设置 UI 标志可以让您对系统栏进行更精细的控制。以下代码段隐藏了状态栏
Kotlin
// Hide the status bar. window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN // Remember that you should never show the action bar if the // status bar is hidden, so hide that too if necessary. actionBar?.hide()
Java
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 标志后(例如,通过离开 Activity),如果您想再次隐藏栏,您的应用需要重置它们。有关如何侦听 UI 可见性更改以便您的应用做出相应响应的讨论,请参阅响应 UI 可见性变化。
- 设置 UI 标志的位置会有影响。如果您在 Activity 的
onCreate()
方法中隐藏系统栏,并且用户按下了主屏幕按钮,则系统栏将重新出现。当用户重新打开 Activity 时,onCreate()
不会被调用,因此系统栏将保持可见。如果您希望系统 UI 更改在用户进出 Activity 时持续存在,请在onResume()
或onWindowFocusChanged()
中设置 UI 标志。 setSystemUiVisibility()
方法仅在调用它的视图可见时才生效。- 离开视图会导致使用
setSystemUiVisibility()
设置的标志被清除。
让内容出现在状态栏后面
在 Android 4.1 及更高版本上,您可以设置应用的内容出现在状态栏后面,这样内容就不会在状态栏隐藏和显示时调整大小。为此,请使用 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
。您可能还需要使用 SYSTEM_UI_FLAG_LAYOUT_STABLE
来帮助您的应用保持稳定的布局。
当您使用此方法时,您有责任确保应用 UI 的关键部分(例如,地图应用中的内置控件)不会被系统栏覆盖。这可能会导致您的应用无法使用。在大多数情况下,您可以通过在 XML 布局文件中添加 android:fitsSystemWindows
属性并将其设置为 true
来处理此问题。这会调整父 ViewGroup
的内边距,为系统窗口留出空间。这对于大多数应用来说已经足够了。
但在某些情况下,您可能需要修改默认内边距,以获得应用所需的布局。要直接控制内容相对于系统栏(占用窗口的“内容内边距”空间)的布局方式,请覆盖 fitSystemWindows(Rect insets)
方法。当窗口的内容内边距发生变化时,视图层次结构会调用 fitSystemWindows()
方法,以便窗口可以相应地调整其内容。通过覆盖此方法,您可以按照自己的意愿处理内边距(以及应用的布局)。