Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fitsSystemWindows removes padding

I have this in my layout:

<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>

But there is no paddingLeft or paddingRight in my app. When I remove fitsSystemWindows, the padding comes back. Why? How can I keep fitsSystemWindows and the padding?

like image 212
user5447353 Avatar asked Oct 15 '15 05:10

user5447353


2 Answers

fitsSyatemWindows attribute overrides the padding applied the layout.

So to apply the padding, you should create one wrapper layout to your RelativeLayout and add fitsSystemWindows attribute to it, and padding to child RelativeLayout.

<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>
like image 151
Apurva Avatar answered Oct 23 '22 03:10

Apurva


I'll just add this here in case anyone needs to remove the top padding when using fitSystemWindows. This may be the case when using custom action bars, DrawerLayout/NavigationView and/or fragments.

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

}

We have to extend the Layout class (FrameLayout in my case) and remove the top padding in the fitSystemWindows() (for API < 20) or onApplyWindowInsets() (for API >= 20).

like image 8
saibotd Avatar answered Oct 23 '22 02:10

saibotd