显示DialogFragment时保持沉浸式模式

Mar*_*ist 8 keyboard android android-dialogfragment android-immersive

我有一个使用Fragments制作的Android应用程序

我使用以下代码隐藏屏幕顶部和底部的条形图.

 @Override
protected void onResume() {
    super.onResume();
    isInBackground = false;

    if(null == getFragmentManager().findFragmentById(R.id.content_container))
    {
        getFragmentManager().beginTransaction().add(R.id.content_container,new PresenterFragment(), PresenterFragment.FRAG_TAG).commit();
    }

    if(Build.VERSION.SDK_INT >=19)
    {
        View decorView = getWindow().getDecorView();
        int uiOptions = 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_STICKY;
        decorView.setSystemUiVisibility(uiOptions);
        decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
            @Override
            public void onSystemUiVisibilityChange(int visibility) {
                View decorView = getWindow().getDecorView();
                int uiOptions = 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_STICKY;
                decorView.setSystemUiVisibility(uiOptions);
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

当它显示条形显示的软键盘时,我可以在键盘被解除时隐藏它.但是如果在显示软键盘时显示对话框片段,那么当键盘和对话框片段都被解除时它们会被禁止保持在应用程序的顶部.

我的3个问题是

是否可以停止软键盘来更改UI模式?

是否可以停止显示DialogsFraments以更改UI模式?

编辑:我曾经在下面的代码中查看键盘是否显示

public static boolean isKeyBoardShown(){
    InputMethodManager imm = (InputMethodManager)currentActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
    if (imm.isAcceptingText()) {
        return true;
    } else {
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

- >我知道在一个活动中有一个解决对话框的工作但我看不到一个或重做代码在DialogFragment中工作

如果两者都不可能,为什么当显示键盘和DialogFrament时,应用程序会陷入错误的UI模式?

Yve*_*omb 33

1.解决方案的解释.

我从android api文档中引用了以下引用.

使用沉浸式全屏模式

启用沉浸式全屏模式后,您的活动将继续接收所有触摸事件.用户可以通过沿系统条通常出现的区域向内滑动来显示系统条.这将清除SYSTEM_UI_FLAG_HIDE_NAVIGATION标志(以及SYSTEM_UI_FLAG_FULLSCREEN标志,如果应用),以便系统栏变为可见.这也会触发您的View.OnSystemUiVisibilityChangeListener(如果已设置).

首先,你不需要OnSystemUiVisibilityChangeListener使用粘性浸泡.

但是,如果您希望系统栏稍后自动隐藏,则可以改为使用SYSTEM_UI_FLAG_IMMERSIVE_STICKY标志.请注意,标志的"粘性"版本不会触发任何侦听器,因为在此模式下临时显示的系统栏处于瞬态状态.

使用粘性/非粘性浸泡建议:

如果您正在构建一个真正身临其境的应用程序,您希望用户在屏幕边缘附近进行交互,并且您不希望他们需要频繁访问系统UI,请将IMMERSIVE_STICKY标志与SYSTEM_UI_FLAG_FULLSCREEN和SYSTEM_UI_FLAG_HIDE_NAVIGATION结合使用.例如,这种方法可能适用于游戏或绘图应用程序.

但是,你提到需要键盘的用户,所以我建议:
使用Non-Sticky Immersion

如果您正在构建图书阅读器,新闻阅读器或杂志,请将IMMERSIVE标志与SYSTEM_UI_FLAG_FULLSCREEN和SYSTEM_UI_FLAG_HIDE_NAVIGATION结合使用.由于用户可能需要稍微频繁地访问操作栏和其他UI控件,但在翻阅内容时不会被任何UI元素所困扰,因此IMMERSIVE对于此用例是一个不错的选择.


2.解决方案

我的解决方案是在片段的onActivityCreated中设置视图ui.

我的例子来自ImmersiveModeFragment.java示例.

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    final View decorView = getActivity().getWindow().getDecorView();
    decorView.setOnSystemUiVisibilityChangeListener(
            new View.OnSystemUiVisibilityChangeListener() {
                @Override
                public void onSystemUiVisibilityChange(int i) {
                    hideSystemUI();
                }
            });
}
Run Code Online (Sandbox Code Playgroud)

创建一个单独的方法来管理从您调用的ui OnSystemUiVisibilityChangeListener()

从这里采取非粘性浸泡

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.
    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 // hide nav bar
        | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
        | View.SYSTEM_UI_FLAG_IMMERSIVE);
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以再次调用此方法onResume.

onResume(){
    hideSystemUI();
}
Run Code Online (Sandbox Code Playgroud)

3.替代解决方案.

如果您真正想要粘性沉浸,则需要尝试不同的方法.

用于粘性浸泡

@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);}
}
Run Code Online (Sandbox Code Playgroud)

我希望这能解决你的问题.


小智 5

我知道这已经很旧了,但我为此苦苦挣扎了一段时间,因为我有dialogFragments 和navigationView 中的下拉菜单,这些下拉菜单不断地不必要地显示系统UI。以下是我所做的最终有效的事情(前两件我在很多地方都找到了):

在我的AndroidManifest.xml申请中

android:theme="@style/AppTheme.NoActionBar"
Run Code Online (Sandbox Code Playgroud)

在我的活动中

View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
decorView.setSystemUiVisibility(uiOptions);
Run Code Online (Sandbox Code Playgroud)

最终成为我的关键的是我的styles.xml

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowFullscreen">true</item>
    </style>
</resources>
Run Code Online (Sandbox Code Playgroud)