首页 > 解决方案 > Android:键盘上方的 FAB 结合 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 标志

问题描述

问题是使用此标志时 FAB 不会停留在键盘上方:

this.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);

我试过了 :

android:fitsSystemWindows="true"

它有效,但它消除了 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 效果。

android:windowSoftInputMode="adjustResize"

这没用。

this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

它也不起作用

有什么建议吗?

标签: androidkeyboardfullscreenfloating-action-buttonflags

解决方案


如果您使用系统 UI 方法( https://developer.android.com/training/system-ui/immersive.html),我刚刚找到了一个简单可靠的解决方案。

它适用于您使用 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 的情况,例如,如果您使用 CoordinatorLayout。

它不适用于 WindowManager.LayoutParams.FLAG_FULLSCREEN (您也可以使用 android:windowFullscreen 在主题中设置),但您可以使用 SYSTEM_UI_FLAG_LAYOUT_STABLE (根据文档“具有相同的视觉效果”)和这个解决方案应该再次起作用。

getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION /* 如果你想隐藏导航 */ | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE)

我已经在运行 Marshmallow 的设备上对其进行了测试。

关键是软键盘也是系统窗口之一(如状态栏和导航栏),所以系统调度的WindowInsets包含准确可靠的信息。

对于我们试图在状态栏后面绘制的 DrawerLayout 等用例,我们可以创建一个仅忽略顶部插图的布局,并应用占软键盘的底部插图。

这是我的自定义 FrameLayout:

/**
 * Implements an effect similar to {@code android:fitsSystemWindows="true"} on Lollipop or higher,
 * except ignoring the top system window inset. {@code android:fitsSystemWindows="true"} does not
 * and should not be set on this layout.
 */
public class FitsSystemWindowsExceptTopFrameLayout extends FrameLayout {

    public FitsSystemWindowsExceptTopFrameLayout(Context context) {
        super(context);
    }

    public FitsSystemWindowsExceptTopFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public FitsSystemWindowsExceptTopFrameLayout(Context context, AttributeSet attrs,
                                                 int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    public FitsSystemWindowsExceptTopFrameLayout(Context context, AttributeSet attrs,
                                                 int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            setPadding(insets.getSystemWindowInsetLeft(), 0, insets.getSystemWindowInsetRight(),
                    insets.getSystemWindowInsetBottom());
            return insets.replaceSystemWindowInsets(0, insets.getSystemWindowInsetTop(), 0, 0);
        } else {
            return super.onApplyWindowInsets(insets);
        }
    }
}

并使用它:

<com.example.yourapplication.FitsSystemWindowsExceptTopFrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- Your original layout here -->
</com.example.yourapplication.FitsSystemWindowsExceptTopFrameLayout>

学分去:@Hai Zhang


推荐阅读