material-components / material-components-android

Modular and customizable Material Design UI components for Android
Apache License 2.0
16.38k stars 3.07k forks source link

[TopAppBar] Horizontal system insets handling #2750

Open pubiqq opened 2 years ago

pubiqq commented 2 years ago

How is the component supposed to handle horizontal system insets?

P.S. This issue is similar to https://github.com/material-components/material-components-android/issues/2696, but it's more general and also related to the specification.

drchen commented 2 years ago

I think it's a general design question (we can't really "move" the layout so I guess the only solution is adding paddings somehow.)

We need to consult our designers to figure out the right behavior here.

MuntashirAkon commented 2 years ago

Those who cannot wait until the issue is fixed, they can use something like below:

import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;

import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.internal.ViewUtils;

public class ResponsiveAppBarLayout extends AppBarLayout {
    public ResponsiveAppBarLayout(@NonNull Context context) {
        this(context, null);
    }

    public ResponsiveAppBarLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, R.attr.appBarLayoutStyle);
    }

    @SuppressLint("RestrictedApi")
    public ResponsiveAppBarLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        ViewUtils.doOnApplyWindowInsets(this, (view, insets, initialPadding) -> {
            if (!ViewCompat.getFitsSystemWindows(view)) {
                return insets;
            }
            initialPadding.top += insets.getSystemWindowInsetTop();
            boolean isRtl = ViewCompat.getLayoutDirection(view) == ViewCompat.LAYOUT_DIRECTION_RTL;
            int systemWindowInsetLeft = insets.getSystemWindowInsetLeft();
            int systemWindowInsetRight = insets.getSystemWindowInsetRight();
            initialPadding.start += isRtl ? systemWindowInsetRight : systemWindowInsetLeft;
            initialPadding.end += isRtl ? systemWindowInsetLeft : systemWindowInsetRight;
            initialPadding.applyToView(view);
            return insets;
        });
    }
}
sebastianharder commented 1 month ago

Since Google is enforcing edge-to-edge now, I am a bit puzzled that such a bug is not fixed since two years. Can we expect some news here soon?