更改活动时,Android Immersive模式会重置

时间:2015-03-21 17:59:27

标签: android android-activity android-immersive

我在使用沉浸式模式时遇到问题。以下是我对所有活动的代码:

 @Override
 public void onWindowFocusChanged(boolean hasFocus) {
     super.onWindowFocusChanged(hasFocus);
     if (hasFocus) {
         getWindow().getDecorView().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
         );
     }
 }

navigationBarstatusBar是不可见的,这很好。

问题是每次我去另一个活动时,navigationBar出现,然后消失。我希望navigationBar看起来不像那样。

5 个答案:

答案 0 :(得分:5)

最简单的工作方式是创建一个基本活动类,如下所示:

public abstract class BaseActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        enableImmersiveMode();
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);

        if(hasFocus) {
            enableImmersiveMode();
        }
    }

    protected void enableImmersiveMode() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            getWindow().getDecorView().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
            );
        }
    }
}

所有应该在沉浸式模式下工作的活动都应该从上面的基类继承。

我刚试过它。它可以防止屏幕菜单在更改活动时隐藏和显示。

答案 1 :(得分:2)

如果你在方法onCreate of activity中调用这么短的代码,如下一个例子:

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
            hideSystemUI();
            ...
   }

 // This snippet hides the system bars.
    private void hideSystemUI() {
        // Set the IMMERSIVE flag.
        // Set the content to appear under the system bars so that the content
        // doesn't resize when the system bars hide and show.
        getWindow().getDecorView().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 // hide nav bar
                        | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
                        | View.SYSTEM_UI_FLAG_IMMERSIVE);
    }

你必须在 onWindowFocusChanged 上调用该方法。

我希望这可以帮助你=)

答案 2 :(得分:2)

也许现在已经很晚了但是现在我遇到了和你一样的问题,偶然发现了这篇文章。由于好奇,我找到了对我有用的解决方案。我手动调用函数“onWindowFocusChanged”并传递“true”参数。我在“setContentView(R.layout.activity_main);”之前在OnCreate中调用了该函数。在添加布局之前执行了该功能并设置了沉浸式模式(全屏),现在我看不到隐藏导航和状态栏的动画。我希望我能帮助你。

这是代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    onWindowFocusChanged(true);
    setContentView(R.layout.activity_main);
}

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

答案 3 :(得分:1)

我也遇到过这个问题。在配置更改后,似乎没有办法阻止Android再次显示导航栏。

更糟糕的是,在确切恢复系统UI时也无法保证。根据我在某些设备上的测试,即使在调用了onWindowFocusChangedonResume之后,导航栏也会重新出现。

我发现防止不需要的UI重新出现的唯一可靠方法是添加isInFullScreenMode布尔标志并实现View.OnSystemUiVisibilityChangeListener这样的内容:

@Override
public void onSystemBarsVisible() {
    if (isInFullScreenMode) {
        // If Android presented system bars 
        // but our app doesn't need them at this point 
        // just call hideSystemUi() again
        hideSystemUi();
        return;
    }
}

@Override
public void onSystemBarsHidden() {
    if (!isInFullScreenMode) {
        // Similar technique as shown above
        showSystemUi();
        return;
    }
}

当然,有时在旋转时我们可以看到系统如何快速出现和消失。但至少我们可以确定我们的应用程序的UI状态将可靠地恢复。

编辑:为了防止可能的混淆(可以在评论中看到),我将澄清一些事情:

  • onSystemBarsVisibleonSystemBarsHidden是我的应用中定义的自定义方法。你不会在Android框架中找到它们;
  • 此处使用override关键字,因为这些方法是合同(接口)的一部分;
  • 我使用此功能的应用程序现已过时。但是,我仍然记得基本想法如下(Kotlin的片段):
fun onSystemUiVisibilityChange(visibility: Int) {
    if (visibility and View.SYSTEM_UI_FLAG_FULLSCREEN == 0) {
        // The system bars are visible
        onSystemBarsVisible()
    } else {
        // The system bars are NOT visible.
        onSystemBarsHidden()
    }
}

答案 4 :(得分:0)

真正的解决方案是拨打setSystemUiVisibilityonResume上的onWindowFocusChanged

@Override
protected void onResume() {
    super.onResume();
    hide();
}

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    hide();
}

public void hide() {
    getWindow().getDecorView().setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
            View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
            View.SYSTEM_UI_FLAG_FULLSCREEN |
            View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY |
            View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE);           
}