【问题标题】:Maintaining "lights-out" mode (View.setSystemUiVisibility) across restarts在重新启动时保持“熄灯”模式 (View.setSystemUiVisibility)
【发布时间】:2012-06-14 05:33:50
【问题描述】:

当我的 Android 应用在最近的手机和平板电脑上运行时,我正在为它设置“熄灯”模式。在我的 onCreate() 方法中,我添加了:

View rootView = getWindow().getDecorView();
rootView.setSystemUiVisibility(View.STATUS_BAR_HIDDEN); // aka View.SYSTEM_UI_FLAG_LOW_PROFILE

这比我想象的要好。在我的 Android 3.2 平板电脑上,状态栏以低调模式启动(栏上的所有按钮都替换为点)。如果我与栏上的按钮交互,它将变得正常,然后返回低调模式(例如,如果我从状态栏中检查配置/通知窗口)。所以看起来这更像是我的应用程序的一个属性,而不是直接隐藏 UI 的“命令”。

不过,有两个极端情况没有处理。首先,如果用户在没有点击任何点的情况下点击状态栏,状态栏就会变为活动状态。它永远不会回到低调模式,直到用户实际与栏上的某些内容进行交互(例如,查看通知或截屏)。因此,如果他们返回与我的应用程序交互,状态栏将不再处于低调模式。 (Gallery 应用程序似乎也有这个问题,所以可能不只是我。)第二个角落案例是来自锁定屏幕的简历。如果我点击电源按钮锁定平板电脑,然后解锁它并恢复应用程序,状态栏将完全可见(并且与其交互不会改变任何内容)。 (图库应用没有这个问题。)

一些博客文章建议我可以设置一个处理程序来监听系统 UI 可见性的变化,然后在它变得可见时重新隐藏 UI。像这样:

rootView.setOnSystemUiVisibilityChangeListener(
  new View.OnSystemUiVisibilityChangeListener() {
    @Override
    public void onSystemUiVisibilityChange(int visibility) {
      if (visibility == View.STATUS_BAR_VISIBLE) {
        game.flagUIIsVisible();
      }
    }
  });

在我的例子中,game 对象上的方法只是设置了一个标志,表示 UI 不可见。稍后,如果我的应用程序中有任何触摸事件(它们由同一个 game 对象处理),并且设置了此标志,那么我会再次调用 STATUS_BAR_HIDDEN 调用。

但是,使用这些回调对 UI 没有明显的影响。我可以看到从一些日志消息中调用了正确的处理程序,并且我可以看到正在调用侦听器。

我也尝试在我的onResume 路径中调用 STATUS_BAR_HIDDEN 调用,但这也没有什么不同。

我正在寻找有关这是某种已知错误的信息,或有关 Gallery 应用程序可能正在执行的操作的提示(假设其执行方式有所不同)。或对其他 API 的尝试建议(或其他可能相关的详细信息)。

我正在使用 libGDX,而我的应用程序只有一个视图,所以它非常简单。该视图也被设置为全屏,libGDX 没有标题。我在清单中将 targetSdkVersion 设置为 15。

【问题讨论】:

    标签: android


    【解决方案1】:

    我怀疑 Android 3.2 中存在错误,因为我可以通过在 onResume 中禁用状态栏之前重新启用状态栏来解决从锁定屏幕恢复的问题。不需要OnSystemUiVisibilityChangeListener

    具体来说,在我的onResume 路径中,我有这样的代码:

    View rootView = getWindow().getDecorView();
    rootView.setSystemUiVisibility(View.STATUS_BAR_VISIBLE);
    rootView.setSystemUiVisibility(View.STATUS_BAR_HIDDEN);
    

    看似不必要的使状态栏可见的调用,似乎使后续调用使状态栏隐藏在解锁设备后真正起作用。

    【讨论】:

      【解决方案2】:

      这里是 Android 4.2,在三星平板电脑上 - 你的解决方案对我不起作用,实际上我设法通过在 onSystemUiVisibilityChange 之后触发的 ValuAnimator 以及 onAnimationEnd 监听器来做到这一点

              topView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
                @Override
                public void onSystemUiVisibilityChange(int visibility) {
                   hideMenu();
                }
              });
      
          private void hideMenu(){
      
          ValueAnimator hideAnim = ValueAnimator.ofInt(1,2);
          hideAnim.setDuration(1);
          hideAnim.addListener(new AnimatorListenerAdapter() {
              @Override
              public void onAnimationEnd(Animator animation) {
                  topView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
              }
          });
          hideAnim.start();
      
      }
      

      【讨论】:

        【解决方案3】:

        这解决了我的问题:

        rootView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
            @Override
            public void onSystemUiVisibilityChange(int visibility) {
                if (visibility == View.SYSTEM_UI_FLAG_VISIBLE) {
                    rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
                    rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
                }
            }
        });
        

        感谢 P.T.!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-05-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多