Skip to content

Commit 384d58f

Browse files
pekingmedsn5ft
authored andcommitted
[Button] Added responsive touch (corner morph).
PiperOrigin-RevId: 637051547
1 parent cb5dc7f commit 384d58f

File tree

12 files changed

+654
-199
lines changed

12 files changed

+654
-199
lines changed

catalog/java/io/material/catalog/button/ButtonToggleGroupDemoFragment.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,17 @@ public View onCreateDemoView(
114114
toggleGroup.setSpacing((int) (value * pixelsInDp));
115115
}
116116
});
117+
MaterialSwitch morphCornerSwitch = view.findViewById(R.id.switch_morph_corner);
118+
morphCornerSwitch.setOnCheckedChangeListener(
119+
(buttonView, isChecked) -> {
120+
for (MaterialButtonToggleGroup toggleGroup : toggleGroups) {
121+
toggleGroup.setCornerAnimationMode(
122+
isChecked
123+
? MaterialButton.CORNER_ANIMATION_MODE_SHRINK_ON_PRESS
124+
| MaterialButton.CORNER_ANIMATION_MODE_GROW_ON_CHECK
125+
: MaterialButton.CORNER_ANIMATION_MODE_NONE);
126+
}
127+
});
117128
return view;
118129
}
119130

catalog/java/io/material/catalog/button/ButtonsMainDemoFragment.java

Lines changed: 56 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,38 @@
2626
import android.view.View;
2727
import android.view.ViewGroup;
2828
import androidx.annotation.LayoutRes;
29+
import androidx.annotation.NonNull;
2930
import androidx.annotation.Nullable;
3031
import com.google.android.material.button.MaterialButton;
3132
import com.google.android.material.snackbar.Snackbar;
3233
import io.material.catalog.feature.DemoFragment;
3334
import io.material.catalog.feature.DemoUtils;
35+
import java.util.ArrayList;
3436
import java.util.List;
3537

3638
/** A fragment that displays main button demos for the Catalog app. */
3739
public class ButtonsMainDemoFragment extends DemoFragment {
3840

41+
@NonNull private List<MaterialButton> buttons = new ArrayList<>();
42+
@NonNull private List<MaterialButton> iconButtons = new ArrayList<>();
43+
@NonNull private SwitchCompat toggleableSwitch;
44+
@NonNull private SwitchCompat enabledSwitch;
45+
@NonNull private SwitchCompat morphCornerSwitch;
46+
3947
@Nullable
4048
@Override
4149
public View onCreateDemoView(
4250
LayoutInflater layoutInflater, @Nullable ViewGroup viewGroup, @Nullable Bundle bundle) {
4351
View view = layoutInflater.inflate(getButtonsContent(), viewGroup, false /* attachToRoot */);
4452

45-
List<MaterialButton> buttons = DemoUtils.findViewsWithType(view, MaterialButton.class);
53+
buttons = DemoUtils.findViewsWithType(view, MaterialButton.class);
54+
55+
ViewGroup iconOnlyButtonsView = view.findViewById(R.id.material_icon_only_buttons_view);
56+
// Icon only buttons demo may not be there in derived demos.
57+
if (iconOnlyButtonsView != null) {
58+
iconButtons = DemoUtils.findViewsWithType(iconOnlyButtonsView, MaterialButton.class);
59+
}
60+
4661
int maxMeasuredWidth = 0;
4762
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
4863

@@ -52,51 +67,57 @@ public View onCreateDemoView(
5267
button.setOnClickListener(
5368
v -> {
5469
// Show a Snackbar with an action button, which should also have a MaterialButton style
55-
Snackbar snackbar =
56-
Snackbar.make(v, R.string.cat_button_clicked, Snackbar.LENGTH_LONG);
70+
Snackbar snackbar = Snackbar.make(v, R.string.cat_button_clicked, Snackbar.LENGTH_LONG);
5771
snackbar.setAction(R.string.cat_snackbar_action_button_text, v1 -> {});
5872
snackbar.show();
5973
});
6074
}
6175

6276
// Using SwitchCompat here to avoid class cast issues in derived demos.
63-
SwitchCompat enabledSwitch = view.findViewById(R.id.cat_button_enabled_switch);
64-
enabledSwitch.setOnCheckedChangeListener(
65-
(buttonView, isChecked) -> {
66-
CharSequence updatedText =
67-
getText(
68-
isChecked
69-
? R.string.cat_button_label_enabled
70-
: R.string.cat_button_label_disabled);
71-
for (MaterialButton button : buttons) {
72-
if (!TextUtils.isEmpty(button.getText())) {
73-
// Do not update icon only button.
74-
button.setText(updatedText);
75-
}
76-
button.setEnabled(isChecked);
77-
button.setFocusable(isChecked);
78-
}
79-
});
77+
enabledSwitch = view.findViewById(R.id.cat_button_enabled_switch);
78+
enabledSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> updateButtons());
8079

81-
ViewGroup iconOnlyButtonsView = view.findViewById(R.id.material_icon_only_buttons_view);
82-
// Icon only buttons demo may not be there in derived demos.
83-
if (iconOnlyButtonsView != null) {
84-
List<MaterialButton> iconButtons =
85-
DemoUtils.findViewsWithType(iconOnlyButtonsView, MaterialButton.class);
86-
// using SwitchCompat here to avoid class cast issues in derived demos.
87-
SwitchCompat toggleableSwitch = view.findViewById(R.id.cat_button_toggleable_icon_buttons);
88-
toggleableSwitch.setOnCheckedChangeListener(
89-
(buttonView, isCheckable) -> {
90-
for (MaterialButton button : iconButtons) {
91-
button.setCheckable(isCheckable);
92-
button.setChecked(false);
93-
}
94-
});
95-
}
80+
// Using SwitchCompat here to avoid class cast issues in derived demos.
81+
toggleableSwitch = view.findViewById(R.id.cat_button_toggleable_icon_buttons);
82+
toggleableSwitch.setOnCheckedChangeListener((buttonView, isCheckable) -> updateIconButtons());
83+
84+
// Using SwitchCompat here to avoid class cast issues in derived demos.
85+
morphCornerSwitch = view.findViewById(R.id.cat_button_morph_corner_switch);
86+
morphCornerSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> updateButtons());
87+
88+
updateButtons();
89+
updateIconButtons();
9690

9791
return view;
9892
}
9993

94+
private void updateButtons() {
95+
boolean isResponsive = morphCornerSwitch.isChecked();
96+
boolean isEnabled = enabledSwitch.isChecked();
97+
CharSequence updatedText =
98+
getText(isEnabled ? R.string.cat_button_label_enabled : R.string.cat_button_label_disabled);
99+
for (MaterialButton button : buttons) {
100+
if (!TextUtils.isEmpty(button.getText())) {
101+
// Do not update icon only button.
102+
button.setText(updatedText);
103+
}
104+
button.setEnabled(isEnabled);
105+
button.setFocusable(isEnabled);
106+
button.setCornerAnimationMode(
107+
isResponsive
108+
? MaterialButton.CORNER_ANIMATION_MODE_SHRINK_ON_PRESS
109+
| MaterialButton.CORNER_ANIMATION_MODE_GROW_ON_CHECK
110+
: MaterialButton.CORNER_ANIMATION_MODE_NONE);
111+
}
112+
}
113+
114+
private void updateIconButtons() {
115+
for (MaterialButton button : iconButtons) {
116+
button.setCheckable(toggleableSwitch.isChecked());
117+
button.setChecked(false);
118+
}
119+
}
120+
100121
@LayoutRes
101122
protected int getButtonsContent() {
102123
return R.layout.cat_buttons_fragment;

catalog/java/io/material/catalog/button/res/layout/cat_buttons_fragment.xml

Lines changed: 107 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -32,97 +32,119 @@
3232
android:paddingBottom="16dp"
3333
android:gravity="center_horizontal"
3434
android:orientation="vertical">
35-
36-
<TextView
37-
android:textStyle="bold"
38-
android:layout_width="wrap_content"
35+
<LinearLayout
36+
android:layout_width="match_parent"
37+
android:layout_height="wrap_content"
38+
android:baselineAligned="false"
39+
android:orientation="horizontal">
40+
<LinearLayout
41+
android:layout_width="0dp"
3942
android:layout_height="wrap_content"
40-
android:paddingTop="8dp"
41-
android:text="@string/cat_btn_text"
42-
android:textSize="16sp"/>
43+
android:layout_weight="1"
44+
android:orientation="vertical"
45+
android:gravity="center_horizontal">
4346

44-
<Button
45-
android:id="@+id/material_button"
46-
android:layout_width="wrap_content"
47-
android:layout_height="wrap_content"
48-
android:text="@string/cat_button_label_enabled"/>
47+
<TextView
48+
android:textStyle="bold"
49+
android:layout_width="wrap_content"
50+
android:layout_height="wrap_content"
51+
android:paddingTop="8dp"
52+
android:text="@string/cat_btn_text"
53+
android:textSize="16sp"/>
4954

50-
<TextView
51-
android:textStyle="bold"
52-
android:layout_width="wrap_content"
53-
android:layout_height="wrap_content"
54-
android:paddingTop="8dp"
55-
android:text="@string/cat_unelevated_btn_text"
56-
android:textSize="16sp"/>
55+
<Button
56+
android:id="@+id/material_button"
57+
android:layout_width="wrap_content"
58+
android:layout_height="wrap_content"
59+
android:text="@string/cat_button_label_enabled"/>
5760

58-
<Button
59-
android:id="@+id/material_unelevated_button"
60-
style="@style/Widget.Material3.Button.UnelevatedButton"
61-
android:layout_width="wrap_content"
62-
android:layout_height="wrap_content"
63-
android:text="@string/cat_button_label_enabled" />
61+
<TextView
62+
android:textStyle="bold"
63+
android:layout_width="wrap_content"
64+
android:layout_height="wrap_content"
65+
android:paddingTop="8dp"
66+
android:text="@string/cat_unelevated_btn_text"
67+
android:textSize="16sp"/>
6468

65-
<TextView
66-
android:textStyle="bold"
67-
android:layout_width="wrap_content"
68-
android:layout_height="wrap_content"
69-
android:paddingTop="8dp"
70-
android:text="@string/cat_icon_btn_text"
71-
android:textSize="16sp"/>
69+
<Button
70+
android:id="@+id/material_unelevated_button"
71+
style="@style/Widget.Material3.Button.UnelevatedButton"
72+
android:layout_width="wrap_content"
73+
android:layout_height="wrap_content"
74+
android:text="@string/cat_button_label_enabled" />
7275

73-
<Button
74-
android:id="@+id/material_icon_button"
75-
style="@style/Widget.Material3.Button.Icon"
76-
android:layout_width="wrap_content"
77-
android:layout_height="wrap_content"
78-
android:text="@string/cat_button_label_enabled"
79-
app:icon="@drawable/ic_dialogs_24px"/>
76+
<TextView
77+
android:textStyle="bold"
78+
android:layout_width="wrap_content"
79+
android:layout_height="wrap_content"
80+
android:paddingTop="8dp"
81+
android:text="@string/cat_icon_btn_text"
82+
android:textSize="16sp"/>
8083

81-
<TextView
82-
android:textStyle="bold"
83-
android:layout_width="wrap_content"
84-
android:layout_height="wrap_content"
85-
android:paddingTop="8dp"
86-
android:text="@string/cat_text_btn_text"
87-
android:textSize="16sp"/>
84+
<Button
85+
android:id="@+id/material_icon_button"
86+
style="@style/Widget.Material3.Button.Icon"
87+
android:layout_width="wrap_content"
88+
android:layout_height="wrap_content"
89+
android:text="@string/cat_button_label_enabled"
90+
app:icon="@drawable/ic_dialogs_24px"/>
8891

89-
<Button
90-
android:id="@+id/material_text_button"
91-
style="@style/Widget.Material3.Button.TextButton"
92-
android:layout_width="wrap_content"
92+
</LinearLayout>
93+
<LinearLayout
94+
android:layout_width="0dp"
9395
android:layout_height="wrap_content"
94-
android:text="@string/cat_button_label_enabled"/>
96+
android:layout_weight="1"
97+
android:orientation="vertical"
98+
android:gravity="center_horizontal">
9599

96-
<TextView
97-
android:textStyle="bold"
98-
android:layout_width="wrap_content"
99-
android:layout_height="wrap_content"
100-
android:paddingTop="8dp"
101-
android:text="@string/cat_icon_text_btn_text"
102-
android:textSize="16sp"/>
100+
<TextView
101+
android:textStyle="bold"
102+
android:layout_width="wrap_content"
103+
android:layout_height="wrap_content"
104+
android:paddingTop="8dp"
105+
android:text="@string/cat_text_btn_text"
106+
android:textSize="16sp"/>
103107

104-
<Button
105-
android:id="@+id/material_icon_text_button"
106-
style="@style/Widget.Material3.Button.TextButton.Icon"
107-
android:layout_width="wrap_content"
108-
android:layout_height="wrap_content"
109-
android:text="@string/cat_button_label_enabled"
110-
app:icon="@drawable/ic_dialogs_24px"/>
108+
<Button
109+
android:id="@+id/material_text_button"
110+
style="@style/Widget.Material3.Button.TextButton"
111+
android:layout_width="wrap_content"
112+
android:layout_height="wrap_content"
113+
android:text="@string/cat_button_label_enabled"/>
111114

112-
<TextView
113-
android:textStyle="bold"
114-
android:layout_width="wrap_content"
115-
android:layout_height="wrap_content"
116-
android:paddingTop="8dp"
117-
android:text="@string/cat_outlined_btn_text"
118-
android:textSize="16sp"/>
115+
<TextView
116+
android:textStyle="bold"
117+
android:layout_width="wrap_content"
118+
android:layout_height="wrap_content"
119+
android:paddingTop="8dp"
120+
android:text="@string/cat_outlined_btn_text"
121+
android:textSize="16sp"/>
119122

120-
<Button
121-
android:id="@+id/material_outlined_button"
122-
style="?attr/materialButtonOutlinedStyle"
123-
android:layout_width="wrap_content"
124-
android:layout_height="wrap_content"
125-
android:text="@string/cat_button_label_enabled"/>
123+
<Button
124+
android:id="@+id/material_outlined_button"
125+
style="?attr/materialButtonOutlinedStyle"
126+
android:layout_width="wrap_content"
127+
android:layout_height="wrap_content"
128+
android:text="@string/cat_button_label_enabled"/>
129+
130+
<TextView
131+
android:textStyle="bold"
132+
android:layout_width="wrap_content"
133+
android:layout_height="wrap_content"
134+
android:paddingTop="8dp"
135+
android:text="@string/cat_icon_text_btn_text"
136+
android:textSize="16sp"/>
137+
138+
<Button
139+
android:id="@+id/material_icon_text_button"
140+
style="@style/Widget.Material3.Button.TextButton.Icon"
141+
android:layout_width="wrap_content"
142+
android:layout_height="wrap_content"
143+
android:text="@string/cat_button_label_enabled"
144+
app:icon="@drawable/ic_dialogs_24px"/>
145+
146+
</LinearLayout>
147+
</LinearLayout>
126148

127149
<TextView
128150
android:textStyle="bold"
@@ -230,9 +252,15 @@
230252
android:id="@+id/cat_button_enabled_switch"
231253
android:layout_width="wrap_content"
232254
android:layout_height="wrap_content"
233-
android:layout_marginTop="16dp"
234255
android:checked="true"
235256
android:text="@string/cat_button_label_enabled"/>
257+
258+
<com.google.android.material.materialswitch.MaterialSwitch
259+
android:id="@+id/cat_button_morph_corner_switch"
260+
android:layout_width="wrap_content"
261+
android:layout_height="wrap_content"
262+
android:checked="false"
263+
android:text="@string/cat_button_morph_corner"/>
236264
</LinearLayout>
237265
</ScrollView>
238266
</androidx.coordinatorlayout.widget.CoordinatorLayout>

catalog/java/io/material/catalog/button/res/layout/cat_buttons_toggle_group_fragment.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,5 +201,15 @@
201201
android:enabled="true"
202202
android:text="@string/cat_button_enable" />
203203

204+
<com.google.android.material.materialswitch.MaterialSwitch
205+
android:id="@+id/switch_morph_corner"
206+
android:paddingTop="16dp"
207+
android:layout_width="wrap_content"
208+
android:layout_height="match_parent"
209+
android:layout_gravity="center"
210+
android:checked="false"
211+
android:enabled="true"
212+
android:text="@string/cat_button_morph_corner" />
213+
204214
</LinearLayout>
205215
</ScrollView>

catalog/java/io/material/catalog/button/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
Flat buttons and raised buttons are the most commonly used types.
2727
</string>
2828
<string name="cat_button_label_enabled">Enabled</string>
29+
<string name="cat_button_morph_corner">Morph Corners</string>
2930
<string name="cat_button_label_disabled">Disabled</string>
3031
<string name="cat_button_icon_btn_text">Icon only button</string>
3132
<string name="cat_btn_text">Material button</string>

0 commit comments

Comments
 (0)