如何在对话框中保持沉浸模式? [英] How do I maintain the Immersive Mode in Dialogs?

查看:80
本文介绍了如何在对话框中保持沉浸模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我的活动显示自定义对话框时,如何维护新的沉浸模式"?

How do I maintain the new Immersive Mode when my activities display a custom Dialog?

我正在使用下面的代码在对话框"中保持沉浸模式",但是使用该解决方案,当我启动自定义对话框时,NavBar会显示不到一秒钟,然后消失.

I am using the code below to maintain the Immersive Mode in Dialogs, but with that solution, the NavBar appears for less than a second when I start my custom Dialog, then it disappears.

以下视频更好地说明了该问题(出现导航栏时,请在屏幕底部查看): http://youtu .be/epnd5ghey8g

The following video explains the issue better (look at the bottom of the screen when the NavBar appears): http://youtu.be/epnd5ghey8g

如何避免这种行为?

代码

我的应用程序中所有活动的父亲:

The father of all activities in my application:

public abstract class ImmersiveActivity extends Activity {

    @SuppressLint("NewApi")
    private void disableImmersiveMode() {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
            getWindow().getDecorView().setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_FULLSCREEN
            );
        }
    }

    @SuppressLint("NewApi")
    private void enableImmersiveMode() {
        if (android.os.Build.VERSION.SDK_INT >= android.os.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_FULLSCREEN 
                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY 
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
            );
        }
    }


    /**
     * Set the Immersive mode or not according to its state in the settings:
     * enabled or not.
     */
    protected void updateSystemUiVisibility() {
        // Retrieve if the Immersive mode is enabled or not.
        boolean enabled = getSharedPreferences(Util.PREF_NAME, 0).getBoolean(
                "immersive_mode_enabled", true);

        if (enabled) enableImmersiveMode();
        else disableImmersiveMode();
    }

    @Override
    public void onResume() {
        super.onResume();
        updateSystemUiVisibility();
    }

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

}



我所有的自定义对话框都在其onCreate(. . .)方法中调用此方法:



All my custom Dialogs call this method in their onCreate(. . .) method:

/**
 * Copy the visibility of the Activity that has started the dialog {@link mActivity}. If the
 * activity is in Immersive mode the dialog will be in Immersive mode too and vice versa.
 */
@SuppressLint("NewApi")
private void copySystemUiVisibility() {
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
        getWindow().getDecorView().setSystemUiVisibility(
                mActivity.getWindow().getDecorView().getSystemUiVisibility()
        );
    }
}



编辑-解决方案(感谢Beaver6813,请查看他的回答以获取更多详细信息):



EDIT - THE SOLUTION (thanks to Beaver6813, look his answer for more details) :

我所有的自定义对话框都以这种方式覆盖show方法:

All my custom dialogs override the show method in this way:

/**
 * An hack used to show the dialogs in Immersive Mode (that is with the NavBar hidden). To
 * obtain this, the method makes the dialog not focusable before showing it, change the UI
 * visibility of the window like the owner activity of the dialog and then (after showing it)
 * makes the dialog focusable again.
 */
@Override
public void show() {
    // Set the dialog to not focusable.
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);

    copySystemUiVisibility();

    // Show the dialog with NavBar hidden.
    super.show();

    // Set the dialog to focusable again.
    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
}

推荐答案

在对该问题进行了大量研究之后,有一个针对此问题的修正程序,其中涉及将Dialog 类来查找.将对话框窗口添加到窗口管理器"时,即使在设置UI可见性之前将其添加到窗口管理器中,也会显示导航栏.在中Android沉浸式示例,其评论如下:

After a lot of research into the issue there is a hacky fix for this, which involved tearing apart the Dialog class to find. The navigation bar is shown when the dialog window is added to the Window Manager even if you set the UI visibility before adding it to the manager. In the Android Immersive example it's commented that:

// * Uses semi-transparent bars for the nav and status bars
// * This UI flag will *not* be cleared when the user interacts with the UI.
// When the user swipes, the bars will temporarily appear for a few seconds and then
// disappear again.

我相信这就是我们在这里看到的(将新的,可聚焦的窗口视图添加到管理器时,将触发用户交互).

I believe that's what we're seeing here (that a user-interaction is being triggered when a new, focusable, window view is added to the manager).

我们如何解决这个问题?在创建对话框时将其设置为非焦点状态(这样我们就不会触发用户交互),然后在显示对话框之后将其设置为焦点状态.

How can we work around this? Make the Dialog non-focusable when we create it (so we don't trigger a user-interaction) and then make it focusable after it's displayed.

//Here's the magic..
//Set the dialog to not focusable (makes navigation ignore us adding the window)
dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);

//Show the dialog!
dialog.show();

//Set the dialog to immersive
dialog.getWindow().getDecorView().setSystemUiVisibility(
context.getWindow().getDecorView().getSystemUiVisibility());

//Clear the not focusable flag from the window
dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);

显然这不是很理想,但似乎是一个Android错误,他们应该检查Window是否具有沉浸式设置.

Clearly this is not ideal but it seems to be an Android bug, they should check if the Window has immersive set.

我已经将我的工作测试代码(原谅过时的杂乱)更新为 Github .我已经在Nexus 5模拟器上进行了测试,它可能会爆破除KitKat之外的任何东西,但仅用于概念验证.

I've updated my working test code (forgive the hacky messiness) to Github. I've tested on the Nexus 5 emulator, it will probably blow up with anything less than KitKat but its for proof-of-concept only.

这篇关于如何在对话框中保持沉浸模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆