沉浸模式显示空白空间

27
我正在尝试实现全屏模式,但对于Android 4.4及以上版本,它会显示一个空白的区域:
在 immersive mode(fullscreen) 之前enter image description heretoggleFullScreen(false); 之后enter image description here 如您所见,它并没有去掉它。这是我用来切换它的代码:
public void toggleFullscreen(boolean fs) {
        if (Build.VERSION.SDK_INT >= 11) {
            // The UI options currently enabled are represented by a bitfield.
            // getSystemUiVisibility() gives us that bitfield.
            int uiOptions = this.getWindow().getDecorView().getSystemUiVisibility();
            int newUiOptions = uiOptions;
            boolean isImmersiveModeEnabled =
                    ((uiOptions | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) == uiOptions);
            if (isImmersiveModeEnabled) {
                Log.i(getPackageName(), "Turning immersive mode mode off. ");
            } else {
                Log.i(getPackageName(), "Turning immersive mode mode on.");
            }

            // Navigation bar hiding:  Backwards compatible to ICS.
            if (Build.VERSION.SDK_INT >= 14) {
                newUiOptions ^= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
            }

            // Status bar hiding: Backwards compatible to Jellybean
            if (Build.VERSION.SDK_INT >= 16) {
                newUiOptions ^= View.SYSTEM_UI_FLAG_FULLSCREEN;
            }

            // Immersive mode: Backward compatible to KitKat.
            // Note that this flag doesn't do anything by itself, it only augments the behavior
            // of HIDE_NAVIGATION and FLAG_FULLSCREEN.  For the purposes of this sample
            // all three flags are being toggled together.
            // Note that there are two immersive mode UI flags, one of which is referred to as "sticky".
            // Sticky immersive mode differs in that it makes the navigation and status bars
            // semi-transparent, and the UI flag does not get cleared when the user interacts with
            // the screen.
            if (Build.VERSION.SDK_INT >= 18) {
                newUiOptions ^= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
            }
            getWindow().getDecorView().setSystemUiVisibility(newUiOptions);
        } else {
            // for android pre 11
            WindowManager.LayoutParams attrs = getWindow().getAttributes();
            if (fs) {
                attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
            } else {
                attrs.flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN;
            }
            this.getWindow().setAttributes(attrs);
        }

        try {
            // hide actionbar
            if
                    (this instanceof AppCompatActivity) {
                if (fs) getSupportActionBar().hide();
                else getSupportActionBar().show();
            } else if
                    (Build.VERSION.SDK_INT >= 11) {
                if (fs) getActionBar().hide();
                else getActionBar().show();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

你找到解决方案了吗?我也遇到了同样的问题。 - glo
@glo,下面给出的解决方案对我有效。请查看此链接中的代码。 - Ankit Aggarwal
@glo 这只发生在 Android L 及以上版本中吗?如果是,这只发生在状态栏还是底部导航栏中也会出现? - Ankit Aggarwal
5个回答

48
请检查您的布局中是否有android:fitsSystemWindows="true"
至少它解决了我的问题 - 我在FrameLayout上使用了fitsSystemWindows。

2
但我并没有使用它,但仍然出现了这个错误之一,而且我真的不明白为什么会出现这个问题。 - Peter
哦!我以为这一行可以解决这个问题。看起来它似乎是默认添加到抽屉布局中的。删除它解决了问题。谢谢。 - Mike Keskinov

6

我是新来的,无法发表评论,但想补充一些关于上述解决方案让我感到非常沮丧的事情。我一直在检查我的活动和其片段是否有 android:fitsSystemWindows="true" ,但它绝对不在那里,然而我仍然在底部有一个间隙!我都快疯了!调整这个简单的东西不能这么难吧!

结果发现它也出现在我添加的导航抽屉中...所以一定要检查所有的XML!


1

只需在您的布局文件中将 android:fitsSystemWindows="true" 更改为 android:fitsSystemWindows="false"。


1

试试这个:

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    var viewParent = view
    while (viewParent is View) {
        viewParent.fitsSystemWindows = false
        viewParent.setOnApplyWindowInsetsListener { _, insets -> insets }
        viewParent = viewParent.parent as View?
    }
}

这是做什么用的?DialogFragment#onActivityCreated() 调用 Dialog#setContentView(),将 Dialog 的视图包装在一个私有的 'wrapInBottomSheet' 中。为了设置这些包装器视图的正确标志,我们希望在它们被包装后设置标志,例如在 super.onActivityCreated() 之后设置。

此外,请观看此讲座以获取有关 fitsSystemWindows 和窗口插图的信息。


0

你需要在你的视图中添加这个标志 View.SYSTEM_UI_FLAG_LAYOUT_STABLE。可以尝试像这样:

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

// This snippet shows the system bars. It does this by removing all the  flags
// except for the ones that make the content appear under the system bars.
private void showSystemUI() {
mDecorView.setSystemUiVisibility(
        View.SYSTEM_UI_FLAG_LAYOUT_STABLE
        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}

嗨@android_Muncher,它没有解决问题,=(,我正在使用Fragment但是从Activity调用togglefullscreen,仍然显示软按钮所在的灰色空间和通知栏所在的黑色空间。 - user2582318
我分享的示例中的mDecorView应该是您需要全屏的视图。无论它是片段还是活动,都没有关系。您可以使用以下代码获取当前视图:final View decorView = getWindow().getDecorView(); - android_Muncher
同样的问题,你能帮忙吗? - Abhishek Tomar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接