Skip to content

Commit d791fad

Browse files
pekingmeimhappi
authored andcommitted
[ButtonGroup] Fixed the bug of size morph not working with layout_weight.
PiperOrigin-RevId: 748859113
1 parent bb90b20 commit d791fad

File tree

2 files changed

+47
-8
lines changed

2 files changed

+47
-8
lines changed

lib/java/com/google/android/material/button/MaterialButton.java

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import android.widget.Checkable;
5757
import android.widget.CompoundButton;
5858
import android.widget.LinearLayout;
59+
import android.widget.LinearLayout.LayoutParams;
5960
import androidx.annotation.AttrRes;
6061
import androidx.annotation.ColorInt;
6162
import 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);

lib/java/com/google/android/material/button/MaterialButtonGroup.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,9 @@ public void addView(@NonNull View child, int index, @Nullable ViewGroup.LayoutPa
206206
return;
207207
}
208208

209+
// Recover the original layout params of all children before adding the new child.
210+
recoverAllChildrenLayoutParams();
211+
209212
isChildrenShapeInvalidated = true;
210213
super.addView(child, index, params);
211214
MaterialButton buttonChild = (MaterialButton) child;
@@ -236,9 +239,19 @@ public void onViewRemoved(View child) {
236239

237240
isChildrenShapeInvalidated = true;
238241
updateChildShapes();
242+
243+
// Recover the original layout params of all children before updating the child layout.
244+
recoverAllChildrenLayoutParams();
239245
adjustChildMarginsAndUpdateLayout();
240246
}
241247

248+
private void recoverAllChildrenLayoutParams(){
249+
for (int i = 0; i < getChildCount(); i++) {
250+
MaterialButton child = getChildButton(i);
251+
child.recoverOriginalLayoutParams();
252+
}
253+
}
254+
242255
@Override
243256
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
244257
updateChildShapes();
@@ -250,6 +263,7 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
250263
protected void onLayout(boolean changed, int l, int t, int r, int b) {
251264
super.onLayout(changed, l, t, r, b);
252265
if (changed) {
266+
recoverAllChildrenLayoutParams();
253267
adjustChildSizeChange();
254268
}
255269
}

0 commit comments

Comments
 (0)