5656import android .widget .Checkable ;
5757import android .widget .CompoundButton ;
5858import android .widget .LinearLayout ;
59+ import android .widget .LinearLayout .LayoutParams ;
5960import androidx .annotation .AttrRes ;
6061import androidx .annotation .ColorInt ;
6162import androidx .annotation .ColorRes ;
@@ -247,6 +248,8 @@ interface OnPressedChangeListener {
247248 @ Px private int originalPaddingStart = UNSET ;
248249 @ Px private int originalPaddingEnd = UNSET ;
249250
251+ @ Nullable private LayoutParams originalLayoutParams ;
252+
250253 // Fields for optical center.
251254 private boolean opticalCenterEnabled ;
252255 private int opticalCenterShift ;
@@ -270,7 +273,7 @@ public MaterialButton(@NonNull Context context, @Nullable AttributeSet attrs) {
270273
271274 public MaterialButton (@ NonNull Context context , @ Nullable AttributeSet attrs , int defStyleAttr ) {
272275 super (
273- wrap (context , attrs , defStyleAttr , DEF_STYLE_RES , new int [] { MATERIAL_SIZE_OVERLAY_ATTR }),
276+ wrap (context , attrs , defStyleAttr , DEF_STYLE_RES , new int [] {MATERIAL_SIZE_OVERLAY_ATTR }),
274277 attrs ,
275278 defStyleAttr );
276279 // Ensure we are using the correctly themed context rather than the context that was passed in.
@@ -324,7 +327,9 @@ private void initializeSizeAnimation() {
324327 }
325328
326329 private SpringForce createSpringForce () {
327- return MotionUtils .resolveThemeSpringForce (getContext (), R .attr .motionSpringFastSpatial ,
330+ return MotionUtils .resolveThemeSpringForce (
331+ getContext (),
332+ R .attr .motionSpringFastSpatial ,
328333 R .style .Motion_Material3_Spring_Standard_Fast_Spatial );
329334 }
330335
@@ -538,7 +543,19 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto
538543 originalWidth = UNSET ;
539544 }
540545 if (originalWidth == UNSET ) {
541- originalWidth = right - left ;
546+ originalWidth = getMeasuredWidth ();
547+ // The width morph leverage the width of the layout params. However, it's not available if
548+ // layout_weight is used. We need to hardcode the width here. The original layout params will
549+ // be preserved for the correctness of distribution when buttons are added or removed into the
550+ // group programmatically.
551+ if (originalLayoutParams == null
552+ && getParent () instanceof MaterialButtonGroup
553+ && ((MaterialButtonGroup ) getParent ()).getButtonSizeChange () != null ) {
554+ originalLayoutParams = (LayoutParams ) getLayoutParams ();
555+ LayoutParams newLayoutParams = new LayoutParams (originalLayoutParams );
556+ newLayoutParams .width = (int ) originalWidth ;
557+ setLayoutParams (newLayoutParams );
558+ }
542559 }
543560
544561 if (allowedWidthDecrease == UNSET ) {
@@ -557,6 +574,14 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto
557574 }
558575 }
559576
577+ void recoverOriginalLayoutParams () {
578+ if (originalLayoutParams != null ) {
579+ setLayoutParams (originalLayoutParams );
580+ originalLayoutParams = null ;
581+ originalWidth = UNSET ;
582+ }
583+ }
584+
560585 @ Override
561586 public void setWidth (@ Px int pixels ) {
562587 originalWidth = UNSET ;
@@ -1539,7 +1564,7 @@ private float getDisplayedWidthIncrease() {
15391564 private void setDisplayedWidthIncrease (float widthIncrease ) {
15401565 if (displayedWidthIncrease != widthIncrease ) {
15411566 displayedWidthIncrease = widthIncrease ;
1542- updatePaddingsAndSize ();
1567+ updatePaddingsAndSizeForWidthAnimation ();
15431568 invalidate ();
15441569 // Report width changed to the parent group.
15451570 if (getParent () instanceof MaterialButtonGroup ) {
@@ -1551,7 +1576,7 @@ private void setDisplayedWidthIncrease(float widthIncrease) {
15511576
15521577 void setDisplayedWidthDecrease (int widthDecrease ) {
15531578 displayedWidthDecrease = min (widthDecrease , allowedWidthDecrease );
1554- updatePaddingsAndSize ();
1579+ updatePaddingsAndSizeForWidthAnimation ();
15551580 invalidate ();
15561581 }
15571582
@@ -1570,7 +1595,7 @@ public void setOpticalCenterEnabled(boolean opticalCenterEnabled) {
15701595 int opticalCenterShift = (int ) (diffX * OPTICAL_CENTER_RATIO );
15711596 if (this .opticalCenterShift != opticalCenterShift ) {
15721597 this .opticalCenterShift = opticalCenterShift ;
1573- updatePaddingsAndSize ();
1598+ updatePaddingsAndSizeForWidthAnimation ();
15741599 invalidate ();
15751600 }
15761601 });
@@ -1582,7 +1607,7 @@ public void setOpticalCenterEnabled(boolean opticalCenterEnabled) {
15821607 post (
15831608 () -> {
15841609 opticalCenterShift = getOpticalCenterShift ();
1585- updatePaddingsAndSize ();
1610+ updatePaddingsAndSizeForWidthAnimation ();
15861611 invalidate ();
15871612 });
15881613 }
@@ -1597,7 +1622,7 @@ public boolean isOpticalCenterEnabled() {
15971622 return opticalCenterEnabled ;
15981623 }
15991624
1600- private void updatePaddingsAndSize () {
1625+ private void updatePaddingsAndSizeForWidthAnimation () {
16011626 int widthChange = (int ) (displayedWidthIncrease - displayedWidthDecrease );
16021627 int paddingStartChange = widthChange / 2 + opticalCenterShift ;
16031628 getLayoutParams ().width = (int ) (originalWidth + widthChange );
0 commit comments