隐藏状态栏

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

图 1 显示了一个带有可见状态栏的应用

system bars

图 1. 可见状态栏。

图 2 显示了一个隐藏了状态栏的应用。请注意,操作栏也已隐藏。您永远不应该在不显示状态栏的情况下显示操作栏。

system bars

图 2. 隐藏状态栏。

在 Android 4.0 及更低版本上隐藏状态栏

您可以通过设置 WindowManager 标志在 Android 4.0(API 级别 14)及更低版本上隐藏状态栏。您可以通过编程方式或通过在应用的清单文件中设置活动主题来执行此操作。如果状态栏应始终在您的应用中保持隐藏状态,则建议在应用的清单文件中设置活动主题(尽管严格来说,如果您愿意,可以通过编程方式覆盖主题)。例如

<application
    ...
    android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen" >
    ...
</application>

使用活动主题的优势如下

  • 它比通过编程方式设置标志更容易维护且错误更少。
  • 它会带来更流畅的 UI 转换,因为系统在实例化应用的主活动之前拥有渲染 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 标志(无论是通过活动主题还是通过编程方式)时,除非您的应用清除这些标志,否则这些标志将保持有效。

您可以使用 FLAG_LAYOUT_IN_SCREEN 将活动布局设置为使用启用 FLAG_FULLSCREEN 时可用的相同屏幕区域。这可以防止在状态栏隐藏和显示时内容大小发生调整。

在 Android 4.1 及更高版本上隐藏状态栏

您可以使用 setSystemUiVisibility() 在 Android 4.1(API 级别 16)及更高版本上隐藏状态栏。setSystemUiVisibility() 在单个视图级别设置 UI 标志;这些设置会聚合到窗口级别。使用 setSystemUiVisibility() 设置 UI 标志可以让您比使用 WindowManager 标志更精细地控制系统栏。此代码段隐藏状态栏

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 标志被清除(例如,通过从活动导航离开),如果要再次隐藏栏,则您的应用需要重置它们。有关如何侦听 UI 可见性更改以使您的应用能够相应地做出响应的讨论,请参阅 响应 UI 可见性更改
  • 设置 UI 标志的位置会产生影响。如果您在活动的 onCreate() 方法中隐藏系统栏,并且用户按了“主页”,则系统栏将重新出现。当用户重新打开活动时,onCreate() 将不会被调用,因此系统栏将保持可见。如果希望系统 UI 更改在用户在活动中导航进出时保持不变,请在 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()方法,以允许窗口相应地调整其内容。通过覆盖此方法,您可以根据需要处理内边距(以及应用程序的布局)。