mirror of
https://github.com/material-components/material-components-android.git
synced 2026-02-20 08:39:55 +08:00
[ButtonToggleGroup] Fix broken corner morph animation by skipping redundant updates
This fix resolves a regression where the corner morph animation in MaterialButtonToggleGroup was abrupt or interrupted in recent versions (1.14.0-alpha07+). The issue was caused by unconditional calls to setShapeAppearanceModel() during layout updates. This triggered a reset in MaterialShapeDrawable (due to stricter checks in recent optimizations), cancelling the ongoing animation. We added a check to compare the calculated corner sizes with the current button's shape. If they are effectively equal, the update is skipped to preserve the ongoing animation. Closes #4990
This commit is contained in:
parent
5cb1500477
commit
720ffd6aa1
@ -693,6 +693,21 @@ public class MaterialButtonGroup extends LinearLayout {
|
||||
originalStateListShapeBuilder
|
||||
.setCornerSizeOverride(innerCornerSize, cornerPositionBitsToOverride)
|
||||
.build();
|
||||
|
||||
// Pre-calculate the default shape to compare with the current one.
|
||||
ShapeAppearanceModel newModel = newStateListShape.getDefaultShape(/* withCornerSizeOverrides= */ true);
|
||||
|
||||
// Get the current shape of the button.
|
||||
ShapeAppearanceModel currentModel = button.getShapeAppearanceModel();
|
||||
|
||||
// If the corner sizes are effectively the same, skip the update.
|
||||
// This prevents the MaterialShapeDrawable from resetting its state,
|
||||
// which would otherwise interrupt the corner morph animation.
|
||||
if (areCornerSizesEqual(currentModel, newModel)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Apply the new shape if it has changed.
|
||||
button.setShapeAppearance(
|
||||
newStateListShape.isStateful()
|
||||
? newStateListShape
|
||||
@ -700,6 +715,20 @@ public class MaterialButtonGroup extends LinearLayout {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the corner sizes of the two {@link ShapeAppearanceModel}s are equal.
|
||||
*
|
||||
* <p>This is used to determine if a shape update is necessary, avoiding redundant updates that
|
||||
* could interrupt ongoing animations.
|
||||
*/
|
||||
private static boolean areCornerSizesEqual(
|
||||
@NonNull ShapeAppearanceModel s1, @NonNull ShapeAppearanceModel s2) {
|
||||
return s1.getTopLeftCornerSize().equals(s2.getTopLeftCornerSize())
|
||||
&& s1.getTopRightCornerSize().equals(s2.getTopRightCornerSize())
|
||||
&& s1.getBottomLeftCornerSize().equals(s2.getBottomLeftCornerSize())
|
||||
&& s1.getBottomRightCornerSize().equals(s2.getBottomRightCornerSize());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link StateListShapeAppearanceModel.Builder} as the original shape of a child
|
||||
* button.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user