From a6011078689521cf0c042e7444c36b6607cedcf9 Mon Sep 17 00:00:00 2001 From: rightnao Date: Tue, 7 Jun 2022 18:17:17 -0700 Subject: [PATCH] [MaterialButton] Add methods to not toggle checked state on buttons on click Resolves https://github.com/material-components/material-components-android/issues/2291 PiperOrigin-RevId: 453569861 --- .../material/button/MaterialButton.java | 24 ++++++++++++- .../material/button/MaterialButtonHelper.java | 12 +++++++ .../button/res-public/values/public.xml | 1 + .../material/button/res/values/attrs.xml | 2 ++ .../material/button/MaterialButtonTest.java | 34 +++++++++++++++++++ 5 files changed, 72 insertions(+), 1 deletion(-) diff --git a/lib/java/com/google/android/material/button/MaterialButton.java b/lib/java/com/google/android/material/button/MaterialButton.java index 962c76b33e6..a3595d77ef9 100644 --- a/lib/java/com/google/android/material/button/MaterialButton.java +++ b/lib/java/com/google/android/material/button/MaterialButton.java @@ -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. * diff --git a/lib/java/com/google/android/material/button/MaterialButtonHelper.java b/lib/java/com/google/android/material/button/MaterialButtonHelper.java index da666c735d4..0fea6158aeb 100644 --- a/lib/java/com/google/android/material/button/MaterialButtonHelper.java +++ b/lib/java/com/google/android/material/button/MaterialButtonHelper.java @@ -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; @@ -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(); @@ -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); diff --git a/lib/java/com/google/android/material/button/res-public/values/public.xml b/lib/java/com/google/android/material/button/res-public/values/public.xml index 6f2eeb4d3bf..60b648b2132 100644 --- a/lib/java/com/google/android/material/button/res-public/values/public.xml +++ b/lib/java/com/google/android/material/button/res-public/values/public.xml @@ -25,6 +25,7 @@ + diff --git a/lib/java/com/google/android/material/button/res/values/attrs.xml b/lib/java/com/google/android/material/button/res/values/attrs.xml index 031e1a85a4d..c7c00919a3d 100644 --- a/lib/java/com/google/android/material/button/res/values/attrs.xml +++ b/lib/java/com/google/android/material/button/res/values/attrs.xml @@ -97,6 +97,8 @@ + + diff --git a/lib/javatests/com/google/android/material/button/MaterialButtonTest.java b/lib/javatests/com/google/android/material/button/MaterialButtonTest.java index d8107d06747..f3cf1efb24c 100644 --- a/lib/javatests/com/google/android/material/button/MaterialButtonTest.java +++ b/lib/javatests/com/google/android/material/button/MaterialButtonTest.java @@ -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() {