56
56
import android .widget .Checkable ;
57
57
import android .widget .CompoundButton ;
58
58
import android .widget .LinearLayout ;
59
+ import android .widget .LinearLayout .LayoutParams ;
59
60
import androidx .annotation .AttrRes ;
60
61
import androidx .annotation .ColorInt ;
61
62
import androidx .annotation .ColorRes ;
@@ -247,6 +248,8 @@ interface OnPressedChangeListener {
247
248
@ Px private int originalPaddingStart = UNSET ;
248
249
@ Px private int originalPaddingEnd = UNSET ;
249
250
251
+ @ Nullable private LayoutParams originalLayoutParams ;
252
+
250
253
// Fields for optical center.
251
254
private boolean opticalCenterEnabled ;
252
255
private int opticalCenterShift ;
@@ -270,7 +273,7 @@ public MaterialButton(@NonNull Context context, @Nullable AttributeSet attrs) {
270
273
271
274
public MaterialButton (@ NonNull Context context , @ Nullable AttributeSet attrs , int defStyleAttr ) {
272
275
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 }),
274
277
attrs ,
275
278
defStyleAttr );
276
279
// Ensure we are using the correctly themed context rather than the context that was passed in.
@@ -324,7 +327,9 @@ private void initializeSizeAnimation() {
324
327
}
325
328
326
329
private SpringForce createSpringForce () {
327
- return MotionUtils .resolveThemeSpringForce (getContext (), R .attr .motionSpringFastSpatial ,
330
+ return MotionUtils .resolveThemeSpringForce (
331
+ getContext (),
332
+ R .attr .motionSpringFastSpatial ,
328
333
R .style .Motion_Material3_Spring_Standard_Fast_Spatial );
329
334
}
330
335
@@ -538,7 +543,19 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto
538
543
originalWidth = UNSET ;
539
544
}
540
545
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
+ }
542
559
}
543
560
544
561
if (allowedWidthDecrease == UNSET ) {
@@ -557,6 +574,14 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto
557
574
}
558
575
}
559
576
577
+ void recoverOriginalLayoutParams () {
578
+ if (originalLayoutParams != null ) {
579
+ setLayoutParams (originalLayoutParams );
580
+ originalLayoutParams = null ;
581
+ originalWidth = UNSET ;
582
+ }
583
+ }
584
+
560
585
@ Override
561
586
public void setWidth (@ Px int pixels ) {
562
587
originalWidth = UNSET ;
@@ -1539,7 +1564,7 @@ private float getDisplayedWidthIncrease() {
1539
1564
private void setDisplayedWidthIncrease (float widthIncrease ) {
1540
1565
if (displayedWidthIncrease != widthIncrease ) {
1541
1566
displayedWidthIncrease = widthIncrease ;
1542
- updatePaddingsAndSize ();
1567
+ updatePaddingsAndSizeForWidthAnimation ();
1543
1568
invalidate ();
1544
1569
// Report width changed to the parent group.
1545
1570
if (getParent () instanceof MaterialButtonGroup ) {
@@ -1551,7 +1576,7 @@ private void setDisplayedWidthIncrease(float widthIncrease) {
1551
1576
1552
1577
void setDisplayedWidthDecrease (int widthDecrease ) {
1553
1578
displayedWidthDecrease = min (widthDecrease , allowedWidthDecrease );
1554
- updatePaddingsAndSize ();
1579
+ updatePaddingsAndSizeForWidthAnimation ();
1555
1580
invalidate ();
1556
1581
}
1557
1582
@@ -1570,7 +1595,7 @@ public void setOpticalCenterEnabled(boolean opticalCenterEnabled) {
1570
1595
int opticalCenterShift = (int ) (diffX * OPTICAL_CENTER_RATIO );
1571
1596
if (this .opticalCenterShift != opticalCenterShift ) {
1572
1597
this .opticalCenterShift = opticalCenterShift ;
1573
- updatePaddingsAndSize ();
1598
+ updatePaddingsAndSizeForWidthAnimation ();
1574
1599
invalidate ();
1575
1600
}
1576
1601
});
@@ -1582,7 +1607,7 @@ public void setOpticalCenterEnabled(boolean opticalCenterEnabled) {
1582
1607
post (
1583
1608
() -> {
1584
1609
opticalCenterShift = getOpticalCenterShift ();
1585
- updatePaddingsAndSize ();
1610
+ updatePaddingsAndSizeForWidthAnimation ();
1586
1611
invalidate ();
1587
1612
});
1588
1613
}
@@ -1597,7 +1622,7 @@ public boolean isOpticalCenterEnabled() {
1597
1622
return opticalCenterEnabled ;
1598
1623
}
1599
1624
1600
- private void updatePaddingsAndSize () {
1625
+ private void updatePaddingsAndSizeForWidthAnimation () {
1601
1626
int widthChange = (int ) (displayedWidthIncrease - displayedWidthDecrease );
1602
1627
int paddingStartChange = widthChange / 2 + opticalCenterShift ;
1603
1628
getLayoutParams ().width = (int ) (originalWidth + widthChange );
0 commit comments