android - 显示 DialogFragment 时保持沉浸式模式

标签 android keyboard android-dialogfragment android-immersive

我有一个使用 fragment 制作的 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);
            }
        });
    }
}

当显示条形图的软键盘显示时,我可以接受它,因为它们在键盘关闭时隐藏。但是,如果在显示软键盘时显示对话框 fragment ,那么当键盘和对话框 fragment 都显示时被驳回,他们的酒吧仍然在应用程序的顶部。

我的 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;
    }
}

-> 我知道 Activity 中的对话框有一个解决方法,但我看不到一个或重新编写代码以在 DialogFragment 中工作

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

最佳答案

<强>1。解决方案说明。

我从 android api 文档中引用了以下内容。

Using Immersive Full-Screen Mode

When immersive full-screen mode is enabled, your activity continues to receive all touch events. The user can reveal the system bars with an inward swipe along the region where the system bars normally appear. This clears the SYSTEM_UI_FLAG_HIDE_NAVIGATION flag (and the SYSTEM_UI_FLAG_FULLSCREEN flag, if applied) so the system bars become visible. This also triggers your View.OnSystemUiVisibilityChangeListener, if set.

首先,使用粘性沉浸时不需要 OnSystemUiVisibilityChangeListener

However, if you'd like the system bars to automatically hide again after a few moments, you can instead use the SYSTEM_UI_FLAG_IMMERSIVE_STICKY flag. Note that the "sticky" version of the flag doesn't trigger any listeners, as system bars temporarily shown in this mode are in a transient state.

recommendations for using sticky/non sticky immersion :

If you're building a truly immersive app, where you expect users to interact near the edges of the screen and you don't expect them to need frequent access to the system UI, use the IMMERSIVE_STICKY flag in conjunction with SYSTEM_UI_FLAG_FULLSCREEN and SYSTEM_UI_FLAG_HIDE_NAVIGATION. For example, this approach might be suitable for a game or a drawing app.

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

If you're building a book reader, news reader, or a magazine, use the IMMERSIVE flag in conjunction with SYSTEM_UI_FLAG_FULLSCREEN and SYSTEM_UI_FLAG_HIDE_NAVIGATION. Because users may want to access the action bar and other UI controls somewhat frequently, but not be bothered with any UI elements while flipping through content, IMMERSIVE is a good option for this use case.


<强>2。解决方案

我的解决方案是在 fragment 的 onActivityCreated 中设置 View 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();
                }
            });
}

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

调用的用户界面

取自此处non sticky immersion

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);
}

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

onResume(){
    hideSystemUI();
}

<强>3。替代解决方案。

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

For sticky immersion

@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);}
}

我希望这能解决您的问题。

关于android - 显示 DialogFragment 时保持沉浸式模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32758559/

相关文章:

android - Android 投影图在内容提供者中的用途是什么?

java - 键盘上方需要一个上一个和下一个按钮

linux - 当用户按下可编辑的 UI 组件时在 Linux 中自动启动键盘

android - DialogFragment 将 EditText 聚焦在为 API 28 打开的对话框上

java - DialogFragment 正在将 XML 扩展到全屏?

android - Activity 泄漏了最初添加到此处的窗口 com.android.internal.policy.impl.PhoneWindow$DecorView@46368a28

android - 在 IntentService 中创建的 Toast 永远不会消失

android - 如何在 C/C++ 中增强 YUV420P 到 RGB 的转换?

c++ - SFML 键盘输入延迟

android - 只有在 onCreate 中设置了适配器和 RecyclerView,才会填充 Fragment 内部的 RecyclerView