From abd1d1c80213054c2b9d3f18bd833b4d20ecbbd5 Mon Sep 17 00:00:00 2001 From: pubiqq Date: Wed, 15 Feb 2023 11:41:48 -0800 Subject: [PATCH] [Snackbar] Fix the snackbar position when the anchor view layout listener is enabled Resolves https://github.com/material-components/material-components-android/pull/3211 Resolves: https://github.com/material-components/material-components-android/issues/3194 GIT_ORIGIN_REV_ID=ef12e5c4f6c6ec49287a472ba1243c20cc2ac979 PiperOrigin-RevId: 509892239 --- .../snackbar/BaseTransientBottomBar.java | 56 +++++++++++++------ 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/lib/java/com/google/android/material/snackbar/BaseTransientBottomBar.java b/lib/java/com/google/android/material/snackbar/BaseTransientBottomBar.java index 49ae1ba4c04..25a63bb9e4f 100644 --- a/lib/java/com/google/android/material/snackbar/BaseTransientBottomBar.java +++ b/lib/java/com/google/android/material/snackbar/BaseTransientBottomBar.java @@ -301,6 +301,7 @@ public void run() { screenHeight - getViewAbsoluteBottom() + (int) view.getTranslationY(); if (currentInsetBottom >= extraBottomMarginGestureInset) { // No need to add extra offset if view is already outside of bottom gesture area + appliedBottomMarginGestureInset = extraBottomMarginGestureInset; return; } @@ -312,6 +313,8 @@ public void run() { return; } + appliedBottomMarginGestureInset = extraBottomMarginGestureInset; + // Move view outside of bottom gesture area MarginLayoutParams marginParams = (MarginLayoutParams) layoutParams; marginParams.bottomMargin += extraBottomMarginGestureInset - currentInsetBottom; @@ -322,9 +325,11 @@ public void run() { private int extraBottomMarginWindowInset; private int extraLeftMarginWindowInset; private int extraRightMarginWindowInset; - private int extraBottomMarginGestureInset; private int extraBottomMarginAnchorView; + private int extraBottomMarginGestureInset; + private int appliedBottomMarginGestureInset; + private boolean pendingShowingView; private List> callbacks; @@ -455,10 +460,16 @@ public boolean performAccessibilityAction(View host, int action, Bundle args) { private void updateMargins() { LayoutParams layoutParams = view.getLayoutParams(); - if (!(layoutParams instanceof MarginLayoutParams) || view.originalMargins == null) { + if (!(layoutParams instanceof MarginLayoutParams)) { Log.w(TAG, "Unable to update margins because layout params are not MarginLayoutParams"); return; } + + if (view.originalMargins == null) { + Log.w(TAG, "Unable to update margins because original view margins are not set"); + return; + } + if (view.getParent() == null) { // Parent will set layout params to view again. Wait for addView() is done to update layout // params, in case we save the already updated margins as the original margins. @@ -467,17 +478,32 @@ private void updateMargins() { int extraBottomMargin = getAnchorView() != null ? extraBottomMarginAnchorView : extraBottomMarginWindowInset; - MarginLayoutParams marginParams = (MarginLayoutParams) layoutParams; - marginParams.bottomMargin = view.originalMargins.bottom + extraBottomMargin; - marginParams.leftMargin = view.originalMargins.left + extraLeftMarginWindowInset; - marginParams.rightMargin = view.originalMargins.right + extraRightMarginWindowInset; - marginParams.topMargin = view.originalMargins.top; - view.requestLayout(); - if (VERSION.SDK_INT >= VERSION_CODES.Q && shouldUpdateGestureInset()) { - // Ensure there is only one gesture inset runnable running at a time - view.removeCallbacks(bottomMarginGestureInsetRunnable); - view.post(bottomMarginGestureInsetRunnable); + MarginLayoutParams marginParams = (MarginLayoutParams) layoutParams; + int newBottomMargin = view.originalMargins.bottom + extraBottomMargin; + int newLeftMargin = view.originalMargins.left + extraLeftMarginWindowInset; + int newRightMargin = view.originalMargins.right + extraRightMarginWindowInset; + int newTopMargin = view.originalMargins.top; + + boolean marginChanged = + marginParams.bottomMargin != newBottomMargin + || marginParams.leftMargin != newLeftMargin + || marginParams.rightMargin != newRightMargin + || marginParams.topMargin != newTopMargin; + if (marginChanged) { + marginParams.bottomMargin = newBottomMargin; + marginParams.leftMargin = newLeftMargin; + marginParams.rightMargin = newRightMargin; + marginParams.topMargin = newTopMargin; + view.requestLayout(); + } + + if (marginChanged || appliedBottomMarginGestureInset != extraBottomMarginGestureInset) { + if (VERSION.SDK_INT >= VERSION_CODES.Q && shouldUpdateGestureInset()) { + // Ensure there is only one gesture inset runnable running at a time + view.removeCallbacks(bottomMarginGestureInsetRunnable); + view.post(bottomMarginGestureInsetRunnable); + } } } @@ -870,11 +896,7 @@ public void onDragStateChanged(int state) { } private void recalculateAndUpdateMargins() { - int newBottomMarginAnchorView = calculateBottomMarginForAnchorView(); - if (newBottomMarginAnchorView == extraBottomMarginAnchorView) { - return; - } - extraBottomMarginAnchorView = newBottomMarginAnchorView; + extraBottomMarginAnchorView = calculateBottomMarginForAnchorView(); updateMargins(); }