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?
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>
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With