Skip to content

Commit 7f8d63b

Browse files
pekingmehunterstich
authored andcommitted
[Button] Added sizes and shape support.
PiperOrigin-RevId: 695840723
1 parent c0231d7 commit 7f8d63b

File tree

5 files changed

+98
-17
lines changed

5 files changed

+98
-17
lines changed

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,17 @@
7272
<string name="cat_snackbar_action_button_text"
7373
description="Text for a snackbar action button. [CHAR LIMIT=NONE]">Done</string>
7474

75+
<string name="cat_filled_button_xsmall_text"
76+
description="Text for filled color extra small variant. [CHAR LIMIT=NONE]">Extra Small Button</string>
77+
<string name="cat_filled_button_small_text"
78+
description="Text for filled color small variant with a note that it is the default style. [CHAR LIMIT=NONE]">Small Button (Default)</string>
79+
<string name="cat_filled_button_medium_text"
80+
description="Text for filled color medium variant. [CHAR LIMIT=NONE]">Medium Button</string>
81+
<string name="cat_filled_button_large_text"
82+
description="Text for filled color large variant. [CHAR LIMIT=NONE]">Large Button</string>
83+
<string name="cat_filled_button_xlarge_text"
84+
description="Text for filled color extra large variant. [CHAR LIMIT=NONE]">Extra Large Button</string>
85+
7586
<string name="cat_single_select">Single-select</string>
7687
<string name="cat_multi_select">Multi-select</string>
7788
<string name="cat_split_button_subheader_filled" translatable="false">Split button, primary</string>

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import android.widget.Checkable;
5656
import android.widget.CompoundButton;
5757
import android.widget.LinearLayout;
58+
import androidx.annotation.AttrRes;
5859
import androidx.annotation.ColorInt;
5960
import androidx.annotation.ColorRes;
6061
import androidx.annotation.DimenRes;
@@ -212,6 +213,8 @@ interface OnPressedChangeListener {
212213

213214
private static final int DEF_STYLE_RES = R.style.Widget_MaterialComponents_Button;
214215

216+
@AttrRes private static final int MATERIAL_SIZE_OVERLAY_ATTR = R.attr.materialSizeOverlay;
217+
215218
// Use Fast Bouncy spring as default.
216219
private static final float DEFAULT_BUTTON_SPRING_DAMPING = 0.6f;
217220
private static final float DEFAULT_BUTTON_SPRING_STIFFNESS = 800f;
@@ -261,7 +264,10 @@ public MaterialButton(@NonNull Context context, @Nullable AttributeSet attrs) {
261264
}
262265

263266
public MaterialButton(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
264-
super(wrap(context, attrs, defStyleAttr, DEF_STYLE_RES), attrs, defStyleAttr);
267+
super(
268+
wrap(context, attrs, defStyleAttr, DEF_STYLE_RES, MATERIAL_SIZE_OVERLAY_ATTR),
269+
attrs,
270+
defStyleAttr);
265271
// Ensure we are using the correctly themed context rather than the context that was passed in.
266272
context = getContext();
267273

lib/java/com/google/android/material/button/res/values/attrs.xml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,4 +159,41 @@
159159

160160
</declare-styleable>
161161

162+
<!-- Container sizes. -->
163+
<!-- These container sizes are only meant to be used in component-level styles and
164+
resources as a means of indirection. They enable remapping to different values
165+
for different size variants. -->
166+
<!-- Container start padding. -->
167+
<attr name="containerPaddingStart" format="dimension"/>
168+
<!-- Container end padding. -->
169+
<attr name="containerPaddingEnd" format="dimension"/>
170+
<!-- Container top padding. -->
171+
<attr name="containerPaddingTop" format="dimension"/>
172+
<!-- Container bottom padding. -->
173+
<attr name="containerPaddingBottom" format="dimension"/>
174+
<!-- Container left inset. Aligned with the InsetDrawable API. -->
175+
<attr name="containerInsetLeft" format="dimension"/>
176+
<!-- Container right inset. Aligned with the InsetDrawable API. -->
177+
<attr name="containerInsetRight" format="dimension"/>
178+
<!-- Container top inset. -->
179+
<attr name="containerInsetTop" format="dimension"/>
180+
<!-- Container bottom inset. -->
181+
<attr name="containerInsetBottom" format="dimension"/>
182+
<!-- Container icon size. -->
183+
<attr name="containerIconSize" format="dimension"/>
184+
<!-- Container icon padding. -->
185+
<attr name="containerIconPadding" format="dimension"/>
186+
<!-- Container stroke width. -->
187+
<attr name="containerStrokeWidth" format="dimension"/>
188+
<!-- Container label text appearance. -->
189+
<attr name="labelTextAppearance" format="reference"/>
190+
<!-- Container shape appearance in default state. -->
191+
<attr name="containerShapeDefault" format="reference"/>
192+
<!-- Container shape appearance in pressed state. -->
193+
<attr name="containerShapePressed" format="reference"/>
194+
<!-- Container shape appearance in checked state. -->
195+
<attr name="containerShapeChecked" format="reference"/>
196+
197+
<attr name="materialSizeOverlay" format="reference" />
198+
162199
</resources>

lib/java/com/google/android/material/theme/overlay/MaterialThemeOverlay.java

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@
4242
*/
4343
public class MaterialThemeOverlay {
4444

45-
private MaterialThemeOverlay() {
46-
}
45+
private MaterialThemeOverlay() {}
4746

4847
private static final int[] ANDROID_THEME_OVERLAY_ATTRS =
4948
new int[] {android.R.attr.theme, R.attr.theme};
@@ -60,23 +59,33 @@ private MaterialThemeOverlay() {
6059
@NonNull
6160
public static Context wrap(
6261
@NonNull Context context,
63-
@Nullable AttributeSet attrs,
62+
@Nullable AttributeSet set,
6463
@AttrRes int defStyleAttr,
65-
@StyleRes int defStyleRes) {
64+
@StyleRes int defStyleRes,
65+
@NonNull int... optionalAttrs) {
6666
int materialThemeOverlayId =
67-
obtainMaterialThemeOverlayId(context, attrs, defStyleAttr, defStyleRes);
68-
boolean contextHasOverlay = context instanceof ContextThemeWrapper
69-
&& ((ContextThemeWrapper) context).getThemeResId() == materialThemeOverlayId;
67+
obtainMaterialThemeOverlayId(context, set, defStyleAttr, defStyleRes);
68+
boolean contextHasOverlay =
69+
context instanceof ContextThemeWrapper
70+
&& ((ContextThemeWrapper) context).getThemeResId() == materialThemeOverlayId;
7071

7172
if (materialThemeOverlayId == 0 || contextHasOverlay) {
7273
return context;
7374
}
7475

7576
Context contextThemeWrapper = new ContextThemeWrapper(context, materialThemeOverlayId);
7677

78+
int[] optionalOverlayIds =
79+
obtainMaterialOverlayIds(context, set, optionalAttrs, defStyleAttr, defStyleRes);
80+
for (int optionalOverlayId : optionalOverlayIds) {
81+
if (optionalOverlayId != 0) {
82+
contextThemeWrapper = new ContextThemeWrapper(contextThemeWrapper, optionalOverlayId);
83+
}
84+
}
85+
7786
// We want values set in android:theme or app:theme to always override values supplied by
7887
// materialThemeOverlay, so we'll wrap the context again if either of those are set.
79-
int androidThemeOverlayId = obtainAndroidThemeOverlayId(context, attrs);
88+
int androidThemeOverlayId = obtainAndroidThemeOverlayId(context, set);
8089
if (androidThemeOverlayId != 0) {
8190
contextThemeWrapper.getTheme().applyStyle(androidThemeOverlayId, true);
8291
}
@@ -106,16 +115,33 @@ private static int obtainAndroidThemeOverlayId(@NonNull Context context, Attribu
106115
@StyleRes
107116
private static int obtainMaterialThemeOverlayId(
108117
@NonNull Context context,
109-
@Nullable AttributeSet attrs,
118+
@Nullable AttributeSet set,
110119
@AttrRes int defStyleAttr,
111120
@StyleRes int defStyleRes) {
112-
TypedArray a =
113-
context.obtainStyledAttributes(
114-
attrs, MATERIAL_THEME_OVERLAY_ATTR, defStyleAttr, defStyleRes);
115-
int materialThemeOverlayId = a.getResourceId(0 /* index */, 0 /* defaultVal */);
116-
a.recycle();
121+
return obtainMaterialOverlayIds(
122+
context, set, MATERIAL_THEME_OVERLAY_ATTR, defStyleAttr, defStyleRes)[0];
123+
}
117124

118-
return materialThemeOverlayId;
125+
/**
126+
* Retrieves the values of an array of Material overlay attributes, taking into account {@code
127+
* defStyleAttr} and {@code defStyleRes} because Material overlay attributes should work from
128+
* default styles.
129+
*/
130+
@NonNull
131+
private static int[] obtainMaterialOverlayIds(
132+
@NonNull Context context,
133+
@Nullable AttributeSet set,
134+
@NonNull int[] attrs,
135+
@AttrRes int defStyleAttr,
136+
@StyleRes int defStyleRes) {
137+
int[] overlayIds = new int[attrs.length];
138+
if (attrs.length > 0) {
139+
TypedArray a = context.obtainStyledAttributes(set, attrs, defStyleAttr, defStyleRes);
140+
for (int i = 0; i < attrs.length; i++) {
141+
overlayIds[i] = a.getResourceId(i, /* defaultVal= */ 0);
142+
}
143+
a.recycle();
144+
}
145+
return overlayIds;
119146
}
120147
}
121-

lib/java/com/google/android/material/theme/res-public/values/public.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,5 @@
7575
<public name="Theme.Design.Light.NoActionBar" type="style"/>
7676

7777
<public name="materialThemeOverlay" type="attr"/>
78+
<public name="materialSizeOverlay" type="attr"/>
7879
</resources>

0 commit comments

Comments
 (0)