Skip to content

Commit

Permalink
[MaterialButton] Add methods to not toggle checked state on buttons o…
Browse files Browse the repository at this point in the history
…n click

Resolves #2291

PiperOrigin-RevId: 453569861
  • Loading branch information
imhappi authored and pekingme committed Jun 8, 2022
1 parent 8dd9c7e commit a601107
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 1 deletion.
24 changes: 23 additions & 1 deletion lib/java/com/google/android/material/button/MaterialButton.java
Expand Up @@ -1212,11 +1212,33 @@ public void toggle() {

@Override
public boolean performClick() {
toggle();
if (materialButtonHelper.isToggleCheckedStateOnClick()) {
toggle();
}

return super.performClick();
}

/**
* Returns whether or not clicking the button will toggle the checked state.
*
* @see #setToggleCheckedStateOnClick(boolean)
* @attr ref R.styleable#toggleCheckedStateOnClick
*/
public boolean isToggleCheckedStateOnClick() {
return materialButtonHelper.isToggleCheckedStateOnClick();
}

/**
* Sets whether or not to toggle the button checked state on click.
*
* @param toggleCheckedStateOnClick whether or not to toggle the checked state on click.
* @attr ref R.styleable#toggleCheckedStateOnClick
*/
public void setToggleCheckedStateOnClick(boolean toggleCheckedStateOnClick) {
materialButtonHelper.setToggleCheckedStateOnClick(toggleCheckedStateOnClick);
}

/**
* Returns whether this MaterialButton is checkable.
*
Expand Down
Expand Up @@ -76,6 +76,7 @@ class MaterialButtonHelper {
private boolean backgroundOverwritten = false;
private boolean cornerRadiusSet = false;
private boolean checkable;
private boolean toggleCheckedStateOnClick = true;
private LayerDrawable rippleDrawable;
private int elevation;

Expand Down Expand Up @@ -117,6 +118,9 @@ void loadFromAttributes(@NonNull TypedArray attributes) {
checkable = attributes.getBoolean(R.styleable.MaterialButton_android_checkable, false);
elevation = attributes.getDimensionPixelSize(R.styleable.MaterialButton_elevation, 0);

toggleCheckedStateOnClick =
attributes.getBoolean(R.styleable.MaterialButton_toggleCheckedStateOnClick, true);

// Store padding before setting background, since background overwrites padding values
int paddingStart = ViewCompat.getPaddingStart(materialButton);
int paddingTop = materialButton.getPaddingTop();
Expand Down Expand Up @@ -362,6 +366,14 @@ boolean isCheckable() {
return checkable;
}

boolean isToggleCheckedStateOnClick() {
return toggleCheckedStateOnClick;
}

void setToggleCheckedStateOnClick(boolean toggleCheckedStateOnClick) {
this.toggleCheckedStateOnClick = toggleCheckedStateOnClick;
}

@Nullable
private MaterialShapeDrawable getSurfaceColorStrokeDrawable() {
return getMaterialShapeDrawable(true);
Expand Down
Expand Up @@ -25,6 +25,7 @@
<public name="iconSize" type="attr"/>
<public name="iconTint" type="attr"/>
<public name="iconTintMode" type="attr"/>
<public name="toggleCheckedStateOnClick" type="attr"/>
<public name="materialButtonStyle" type="attr"/>
<public name="materialIconButtonStyle" type="attr"/>
<public name="materialIconButtonFilledStyle" type="attr"/>
Expand Down
Expand Up @@ -97,6 +97,8 @@
<!-- Ripple color for the button. This may be a color state list, if the desired ripple color
should be stateful. Attribute type definition is in resources package. -->
<attr name="rippleColor"/>
<!-- Whether the button toggles the checked state when clicked. -->
<attr name="toggleCheckedStateOnClick" format="boolean"/>
</declare-styleable>

<declare-styleable name="MaterialButtonToggleGroup">
Expand Down
Expand Up @@ -148,6 +148,40 @@ public void setIcon_iconUpdated_whenCalledTwice() {
assertThat(unwrapDrawable).isEqualTo(drawable2);
}

@Test
public void checkedStateTogglesOnClick() {
MaterialButton materialButton = new MaterialButton(context);
materialButton.setCheckable(true);

materialButton.performClick();
assertThat(materialButton.isChecked()).isTrue();

materialButton.performClick();
assertThat(materialButton.isChecked()).isFalse();
}

@Test
public void togglingCheckedStateTogglesOnClick() {
MaterialButton materialButton = new MaterialButton(context);
materialButton.setCheckable(true);
assertThat(materialButton.isChecked()).isFalse();

materialButton.setToggleCheckedStateOnClick(false);
materialButton.performClick();
assertThat(materialButton.isChecked()).isFalse();
}

@Test
public void setToggleCheckedStateOnClick() {
MaterialButton materialButton = new MaterialButton(context);
materialButton.setCheckable(true);

assertThat(materialButton.isToggleCheckedStateOnClick()).isTrue();

materialButton.setToggleCheckedStateOnClick(false);
assertThat(materialButton.isToggleCheckedStateOnClick()).isFalse();
}

@Test
@Config(minSdk = 23, maxSdk = 28)
public void setIcon_iconNotUpdated_whenPositionChanged() {
Expand Down

0 comments on commit a601107

Please sign in to comment.