fitsSystemWindows 删除填充

fitsSystemWindows removes padding

我的布局中有这个:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/primary"
    android:paddingLeft="32dp"
    android:paddingRight="32dp"
    android:fitsSystemWindows="true">

    ...

</RelativeLayout>

但我的应用程序中没有 paddingLeftpaddingRight。当我删除 fitsSystemWindows 时,填充又回来了。为什么?如何保留 fitsSystemWindows 和填充?

fitsSyatemWindows 属性 覆盖 应用布局的填充。

因此,要应用填充,您应该为 RelativeLayout 创建一个包装器布局并向其添加 fitsSystemWindows 属性,并向子 RelativeLayout 添加 padding

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/primary"
    android:fitsSystemWindows="true">        //this is container layout

    <RelativeLayout
         android:paddingLeft="32dp"
         android:paddingRight="32dp"
         ..... >                            //now you can add padding to this

          .....

    </RelativeLayout>
</RelativeLayout>

我将在此处添加此内容,以防有人在使用 fitSystemWindows 时需要删除顶部填充。使用自定义操作栏时可能会出现这种情况,DrawerLayout/NavigationView and/or个碎片。

public class CustomFrameLayout extends FrameLayout {
    public CustomFrameLayout(Context context) {
        super(context);
    }

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

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

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

    @Override
    protected boolean fitSystemWindows(Rect insets) {
        // this is added so we can "consume" the padding which is added because
        // `android:fitsSystemWindows="true"` was added to the XML tag of View.
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN
                && Build.VERSION.SDK_INT < 20) {
            insets.top = 0;
            // remove height of NavBar so that it does add padding at bottom.
            insets.bottom -= heightOfNavigationBar;
        }
        return super.fitSystemWindows(insets);
    }

    @Override
    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
        // executed by API >= 20.
        // removes the empty padding at the bottom which equals that of the height of NavBar.
        setPadding(0, 0, 0, insets.getSystemWindowInsetBottom() - heightOfNavigationBar);
        return insets.consumeSystemWindowInsets();
    }

}

我们必须扩展布局 class(在我的例子中是 FrameLayout)并删除 fitSystemWindows() 中的顶部填充(对于 API < 20)或 onApplyWindowInsets() (对于 API >= 20)。