From 2bfc7bae0778c8fa20308d2bf434ca1f5cc38cce Mon Sep 17 00:00:00 2001 From: conradchen Date: Thu, 28 Apr 2022 11:35:42 -0400 Subject: [PATCH] [SnackBar] Fix margins are added multiple times when show() is called When a snack bar is hidden and its show() method is called, it will be added to the target parent, and at this moment the parent view will set the layout params to the snack bar, with the same existing margins if any. Therefore if the margins are already updated with extra margins, the original margins will be incorrectly updated. This CL introduces a flag to tells this situation from other "real" scenarios in which clients want to update their custom margins. Resolves https://github.com/material-components/material-components-android/issues/2666 PiperOrigin-RevId: 445159923 (cherry picked from commit 46fa8cc45b8bb6d1423f7349986c7f3f4cdc5d4e) --- .../material/snackbar/BaseTransientBottomBar.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/java/com/google/android/material/snackbar/BaseTransientBottomBar.java b/lib/java/com/google/android/material/snackbar/BaseTransientBottomBar.java index e64fbe8ce8a..b791e76cd03 100644 --- a/lib/java/com/google/android/material/snackbar/BaseTransientBottomBar.java +++ b/lib/java/com/google/android/material/snackbar/BaseTransientBottomBar.java @@ -712,7 +712,7 @@ final void showView() { setUpBehavior((CoordinatorLayout.LayoutParams) lp); } - targetParent.addView(this.view); + this.view.addToTargetParent(targetParent); recalculateAndUpdateMargins(); // Set view to INVISIBLE so it doesn't flash on the screen before the inset adjustment is @@ -1111,6 +1111,7 @@ public boolean onTouch(View v, MotionEvent event) { private PorterDuff.Mode backgroundTintMode; @Nullable private Rect originalMargins; + private boolean addingToTargetParent; protected SnackbarBaseLayout(@NonNull Context context) { this(context, null); @@ -1233,7 +1234,10 @@ protected void onDetachedFromWindow() { @Override public void setLayoutParams(ViewGroup.LayoutParams params) { super.setLayoutParams(params); - if (params instanceof MarginLayoutParams) { + if (!addingToTargetParent && params instanceof MarginLayoutParams) { + // Do not update the original margins when the layout is being added to its target parent, + // since the margins are just copied from the existing layout params, which can already be + // updated with extra margins. updateOriginalMargins((MarginLayoutParams) params); if (baseTransientBottomBar != null) { baseTransientBottomBar.updateMargins(); @@ -1266,6 +1270,12 @@ int getMaxInlineActionWidth() { return maxInlineActionWidth; } + void addToTargetParent(ViewGroup targetParent) { + addingToTargetParent = true; + targetParent.addView(this); + addingToTargetParent = false; + } + private void setBaseTransientBottomBar(BaseTransientBottomBar baseTransientBottomBar) { this.baseTransientBottomBar = baseTransientBottomBar; }