欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

使用沉浸式全屏模式

程序员文章站 2024-03-22 23:44:04
...

“虽然在android4.0之后就引入了虚拟键,但是google真正解决虚拟键所带来的困扰是在4.4版本之后。这篇文章就是教你如何彻底解决虚拟键带来的问题。在前面的几篇文章中我们已经知道如何同时隐藏状态栏和导航栏,按理说已经全屏了 ,但是前面的的这些方法都有个缺点,在全屏的时候用户不能有任何的交互行为,否则全屏效果将消失。(google这样设计的目的是为了让虚拟键能继续发挥它的作用,总要在全屏之后找个时机让虚拟键出来吧,但是这种时机其实不能满足绝大多数需求,这种设计是有问题的,因为显然我们有在全屏模式下也能交互的需求。)”
Android 4.4(API Level 19)引入了一个新 SYSTEM_UI_FLAG_IMMERSIVE标志 setSystemUiVisibility(),可以让您的应用真正实现“全屏”。此标志与SYSTEM_UI_FLAG_HIDE_NAVIGATION和 SYSTEM_UI_FLAG_FULLSCREEN标志组合时 隐藏导航和状态栏,并让您的应用程序捕获屏幕上的所有触摸事件。

当启用沉浸式的全屏模式时,您的活动将继续接收所有触摸事件。用户可以通过沿系统栏通常出现的区域向内轻扫来显示系统栏。这将清除(SYSTEM_UI_FLAG_FULLSCREEN),以便系统栏可见。这也触发你设置的 View.OnSystemUiVisibilityChangeListener,但是,如果您希望系统栏在片刻后自动再次隐藏,则可以改为使用该 SYSTEM_UI_FLAG_IMMERSIVE_STICKY标志。请注意,该标记的“粘滞”版本不会触发任何侦听器,因为此模式中临时显示的系统条状态处于瞬态状态。

图1展示了不同的“沉浸模式”状态:
使用沉浸式全屏模式
图1.沉浸模式状态。
在图1中:
1、非沉浸式模式 - 这是应用程序进入沉浸式模式之前的样子。应用程序出现 ,用户滑动显示系统栏,从而清除SYSTEM_UI_FLAG_HIDE_NAVIGATIONSYSTEM_UI_FLAG_FULLSCREEN标志。一旦这些标志被清除,系统条就会重新出现并保持可见状态。这也是为什么使用IMMERSIVE

注意:最好的做法是保持所有UI控件与系统栏同步,以最大限度地减少屏幕可以使用的状态数。这提供了更加无缝的用户体验。所以这里所有的UI控件都与状态栏一起显示。一旦应用程序进入沉浸式模式,UI控件将与系统栏一起隐藏。为了确保您的UI可见性与系统栏可见性保持同步,请确保提供适当View.OnSystemUiVisibilityChangeListener 的监视更改,如 响应UI可见性更改中所述。

2、提醒泡泡 - 用户首次在您的应用中进入沉浸模式时,系统会显示提醒泡泡。提醒气泡提醒用户如何显示系统栏。

注意:如果您想强制提醒气泡出于测试目的,可以将应用置于沉浸模式,使用电源按钮关闭屏幕,然后在5秒内重新打开屏幕。

3、沉浸模式 - 这是沉浸式模式下的应用程序,隐藏了系统栏和其他UI控件。无论是 IMMERSIVEIMMERSIVE_STICKY 你都能达到这个状态

4、粘滞标志 - IMMERSIVE_STICKY 设置的用户界面,用户滑动时系统栏会半透明条暂时出现,然后再次隐藏。滑动行为不会清除任何标志,也不会触发系统UI可见性更改侦听器,因为系统条的瞬态外观不被视为UI可见性更改。

注意:请记住,IMMERSIVE标志才能生效,如果你可以同时使用它们SYSTEM_UI_FLAG_HIDE_NAVIGATIONSYSTEM_UI_FLAG_FULLSCREEN或两者兼而有之。您可以只使用其中一种,但在实施“IMMERSIVE”模式时,通常隐藏状态和导航栏

选择一种方法

SYSTEM_UI_FLAG_IMMERSIVESYSTEM_UI_FLAG_IMMERSIVE_STICKY两者都提供了一种沉浸式的体验

  • 图书阅读器,新闻阅读器或杂志,请将该IMMERSIVESYSTEM_UI_FLAG_FULLSCREENandSYSTEM_UI_FLAG_HIDE_NAVIGATION 结合使用。由于用户可能想要频繁访问操作栏和其他UI控件,但在浏览内容时不会受到任何UI元素的困扰, IMMERSIVE因此对于此用例来说是一个不错的选择。

    • 如果您正在构建一款沉浸式的应用程序,您希望用户在屏幕边缘附近进行交互,并且您不希望他们需要频繁访问系统UI,请将此 IMMERSIVE_STICKYSYSTEM_UI_FLAG_FULLSCREENandSYSTEM_UI_FLAG_HIDE_NAVIGATION结合使用。例如:游戏或绘图应用程序。

使用非粘滞

当您使用SYSTEM_UI_FLAG_IMMERSIVE标志时,它会根据您设置的其他UI标志(SYSTEM_UI_FLAG_HIDE_NAVIGATION, SYSTEM_UI_FLAG_FULLSCREEN,或两者)来隐藏系统栏。
当用户在系统栏区域向内滑动时,系统栏会重新出现并保持可见状态

包含其他系统UI标志(如SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATIONSYSTEM_UI_FLAG_LAYOUT_STABLE)以避免在系统栏隐藏和显示时调整内容的大小是一种很好的做法 。您还应该确保操作栏和其他UI控件同时隐藏。此片段演示如何隐藏和显示状态和导航栏,而不调整内容大小:

// This snippet hides the system bars.
private void hideSystemUI() {
    /设置IMMERSIVE。 
    //将内容设置为出现在系统栏下方以便显示内容 
    //在系统栏隐藏并显示时不会调整大小。
    mDecorView.setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // 隐藏导航栏            | View.SYSTEM_UI_FLAG_FULLSCREEN // 隐藏状态栏
            | View.SYSTEM_UI_FLAG_IMMERSIVE);
}

//这段代码显示系统栏。它通过删除所有标志来完成此操作
//除了那些使内容出现在系统栏下的内容外。
private void showSystemUI() {
    mDecorView.setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}

您可能还想与IMMERSIVE标志一起实施以下内容 以提供更好的用户体验:

  • 注册一个侦听器,以便您的应用可以得到系统UI可见性更改的通知,如响应UI可见性更改中所述
  • 执行onWindowFocusChanged()。如果您获得窗口焦点,则可能需要重新隐藏系统栏。如果您失去了窗口焦点(例如由于应用程序上方显示的对话框或弹出式菜单),您可能需要取消之前预定的任何待执行的“隐藏”操作Handler.postDelayed()或类似操作。
  • 实施GestureDetector检测 onSingleTapUp(MotionEvent),以允许用户通过触摸您的内容手动切换系统栏的可见性。简单的点击监听器并不是最好的解决方案,因为即使用户在屏幕上拖动手指(假设点击目标占据整个屏幕),它们也会被触发。

响应UI可见性更改

介绍如何注册侦听器,以便您的应用可以获知系统UI可见性更改的通知。如果您想要将用户界面的其他部分与隐藏/显示系统栏同步,这非常有用。

注册一个监听器

要获得系统UI可见性更改的通知,请View.OnSystemUiVisibilityChangeListener在您的视图中注册一个 。这通常是您用来控制导航可见性的视图。

例如,您可以将此代码添加到您的活动的 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:系统栏可见。做任何想要的
            //调整你的用户界面,比如显示操作栏或者
            //其他导航控件。
        } else {
            // TODO:系统栏不可见。做任何想要的 
            //调整你的用户界面,比如隐藏操作栏或者 
            //其他导航控件。
        }
    }
});

通常,保持UI与系统栏可见性更改同步是一种很好的做法。例如,您可以使用此侦听器来隐藏和显示与状态栏隐藏和显示一致的操作栏。

使用粘滞浸入

当您使用该SYSTEM_UI_FLAG_IMMERSIVE_STICKY标志时,系统栏区域中的向内滑动会导致该栏暂时显示为半透明状态,但不会清除标志,并且系统UI可见性更改侦听器不会被触发。在短暂延迟后,或者用户与屏幕中间进行交互时,条形图会自动再次隐藏。

图2显示了半透明系统栏,当您使用该IMMERSIVE_STICKY标志时,系统栏会短暂出现,然后再次隐藏。

使用沉浸式全屏模式

图2.自动隐藏系统栏。

以下是使用此标志的简单方法。只要窗口获得焦点,只需设置IMMERSIVE_STICKY标志以及Use IMMERSIVE中讨论的其他标志即可。例如:

@Override
public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
    if (hasFocus) {
        decorView.setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_FULLSCREEN
                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
    }
}

注意:如果您喜欢自动隐藏行为 IMMERSIVE_STICKY 但需要显示自己的UI控件,只需 IMMERSIVE结合使用 Handler.postDelayed()或类似的东西在几秒钟后重新进入沉浸式模式。

其他示例代码

要下载有关沉浸式模式的示例应用程序,请参阅 Android ImmersiveMode示例, Android BasicImmersiveMode示例和 Android AdvancedImmersiveMode示例。