From a71781355e48eb6106fc42bd4237027b71e8d803 Mon Sep 17 00:00:00 2001 From: dsn5ft <1420597+dsn5ft@users.noreply.github.com> Date: Wed, 27 Apr 2022 12:35:35 -0400 Subject: [PATCH] [Snackbar] Add shape theming support and update M3 style to use new shapeAppearanceCornerExtraSmall PiperOrigin-RevId: 444883546 --- docs/components/Snackbar.md | 15 ++++--- .../snackbar/BaseTransientBottomBar.java | 45 +++++++++++++++---- .../material/snackbar/res/values/attrs.xml | 6 +++ .../material/snackbar/res/values/styles.xml | 5 ++- 4 files changed, 55 insertions(+), 16 deletions(-) diff --git a/docs/components/Snackbar.md b/docs/components/Snackbar.md index b95e50c1d40..dfffd27d0a1 100644 --- a/docs/components/Snackbar.md +++ b/docs/components/Snackbar.md @@ -176,13 +176,14 @@ Element | Attribute | Related method(s) | Default va ### Container attributes -Element | Attribute | Related method(s) | Default value ------------------------ | --------------------------------- | ----------------------------------------------- | ------------- -**Color** | `app:backgroundTint` | `setBackgroundTint`
`setBackgroundTintList` | `?attr/colorSurfaceInverse` -**Color overlay alpha** | `app:backgroundOverlayColorAlpha` | N/A | `0.8f` (ignored if `app:backgroundTint` is set) -**Margin** | `android:layout_margin` | N/A | `8dp` -**Elevation** | `app:elevation` | N/A | `6dp` -**Animation mode** | `app:animationMode` | `setAnimationMode`
`getAnimationMode` | `fade` +Element | Attribute | Related method(s) | Default value +----------------------- | ------------------------------------------------------ | ----------------------------------------------- | ------------- +**Color** | `app:backgroundTint` | `setBackgroundTint`
`setBackgroundTintList` | `?attr/colorSurfaceInverse` +**Color overlay alpha** | `app:backgroundOverlayColorAlpha` | N/A | `0.8f` (ignored if `app:backgroundTint` is set) +**Shape** | `app:shapeAppearance`
`app:shapeAppearanceOverlay` | N/A | `?attr/shapeAppearanceCornerExtraSmall` +**Margin** | `android:layout_margin` | N/A | `8dp` +**Elevation** | `app:elevation` | N/A | `6dp` +**Animation mode** | `app:animationMode` | `setAnimationMode`
`getAnimationMode` | `fade` ### Action attributes diff --git a/lib/java/com/google/android/material/snackbar/BaseTransientBottomBar.java b/lib/java/com/google/android/material/snackbar/BaseTransientBottomBar.java index e64fbe8ce8a..333fcac7324 100644 --- a/lib/java/com/google/android/material/snackbar/BaseTransientBottomBar.java +++ b/lib/java/com/google/android/material/snackbar/BaseTransientBottomBar.java @@ -33,6 +33,7 @@ import android.annotation.SuppressLint; import android.content.Context; import android.content.res.ColorStateList; +import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.PorterDuff; import android.graphics.Rect; @@ -61,6 +62,7 @@ import android.view.WindowManager; import android.view.accessibility.AccessibilityManager; import android.widget.FrameLayout; +import androidx.annotation.ColorInt; import androidx.annotation.IdRes; import androidx.annotation.IntDef; import androidx.annotation.IntRange; @@ -81,6 +83,8 @@ import com.google.android.material.internal.ThemeEnforcement; import com.google.android.material.internal.ViewUtils; import com.google.android.material.resources.MaterialResources; +import com.google.android.material.shape.MaterialShapeDrawable; +import com.google.android.material.shape.ShapeAppearanceModel; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; @@ -1102,6 +1106,7 @@ public boolean onTouch(View v, MotionEvent event) { }; @Nullable private BaseTransientBottomBar baseTransientBottomBar; + @Nullable ShapeAppearanceModel shapeAppearanceModel; @AnimationMode private int animationMode; private final float backgroundOverlayColorAlpha; private final float actionTextColorAlpha; @@ -1127,6 +1132,13 @@ protected SnackbarBaseLayout(@NonNull Context context, AttributeSet attrs) { this, a.getDimensionPixelSize(R.styleable.SnackbarLayout_elevation, 0)); } animationMode = a.getInt(R.styleable.SnackbarLayout_animationMode, ANIMATION_MODE_SLIDE); + if (a.hasValue(R.styleable.SnackbarLayout_shapeAppearance) + || a.hasValue(R.styleable.SnackbarLayout_shapeAppearanceOverlay)) { + shapeAppearanceModel = + ShapeAppearanceModel.builder( + context, attrs, /* defStyleAttr= */ 0, /* defStyleRes= */ 0) + .build(); + } backgroundOverlayColorAlpha = a.getFloat(R.styleable.SnackbarLayout_backgroundOverlayColorAlpha, 1); setBackgroundTintList( @@ -1277,17 +1289,15 @@ private void updateOriginalMargins(MarginLayoutParams params) { @NonNull private Drawable createThemedBackground() { - float cornerRadius = - getResources().getDimension(R.dimen.mtrl_snackbar_background_corner_radius); - - GradientDrawable background = new GradientDrawable(); - background.setShape(GradientDrawable.RECTANGLE); - background.setCornerRadius(cornerRadius); - int backgroundColor = MaterialColors.layer( this, R.attr.colorSurface, R.attr.colorOnSurface, getBackgroundOverlayColorAlpha()); - background.setColor(backgroundColor); + // Only use newer MaterialShapeDrawable background approach if shape appearance is set, in + // order to preserve the original GradientDrawable background for pre-M3 Snackbars. + Drawable background = + shapeAppearanceModel != null + ? createMaterialShapeDrawableBackground(backgroundColor, shapeAppearanceModel) + : createGradientDrawableBackground(backgroundColor, getResources()); if (backgroundTint != null) { Drawable wrappedDrawable = DrawableCompat.wrap(background); DrawableCompat.setTintList(wrappedDrawable, backgroundTint); @@ -1298,6 +1308,25 @@ private Drawable createThemedBackground() { } } + @NonNull + private static MaterialShapeDrawable createMaterialShapeDrawableBackground( + @ColorInt int backgroundColor, @NonNull ShapeAppearanceModel shapeAppearanceModel) { + MaterialShapeDrawable background = new MaterialShapeDrawable(shapeAppearanceModel); + background.setFillColor(ColorStateList.valueOf(backgroundColor)); + return background; + } + + @NonNull + private static GradientDrawable createGradientDrawableBackground( + @ColorInt int backgroundColor, @NonNull Resources resources) { + float cornerRadius = resources.getDimension(R.dimen.mtrl_snackbar_background_corner_radius); + GradientDrawable background = new GradientDrawable(); + background.setShape(GradientDrawable.RECTANGLE); + background.setCornerRadius(cornerRadius); + background.setColor(backgroundColor); + return background; + } + /** Behavior for {@link BaseTransientBottomBar}. */ public static class Behavior extends SwipeDismissBehavior { @NonNull private final BehaviorDelegate delegate; diff --git a/lib/java/com/google/android/material/snackbar/res/values/attrs.xml b/lib/java/com/google/android/material/snackbar/res/values/attrs.xml index 9cca545cd67..5eec57d8dca 100644 --- a/lib/java/com/google/android/material/snackbar/res/values/attrs.xml +++ b/lib/java/com/google/android/material/snackbar/res/values/attrs.xml @@ -47,6 +47,12 @@ + + + + diff --git a/lib/java/com/google/android/material/snackbar/res/values/styles.xml b/lib/java/com/google/android/material/snackbar/res/values/styles.xml index 056b0b9c1c1..20ad30c011e 100644 --- a/lib/java/com/google/android/material/snackbar/res/values/styles.xml +++ b/lib/java/com/google/android/material/snackbar/res/values/styles.xml @@ -80,10 +80,13 @@ @null @dimen/m3_snackbar_margin fade + ?attr/shapeAppearanceCornerExtraSmall -