Skip to content

Commit fb96aa8

Browse files
ikim24hunterstich
authored andcommitted
[Catalog] Update theme switcher to have customizable radio button styling
PiperOrigin-RevId: 358218881
1 parent d6ddf00 commit fb96aa8

File tree

3 files changed

+138
-67
lines changed

3 files changed

+138
-67
lines changed

catalog/java/io/material/catalog/tableofcontents/TocModule.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import io.material.catalog.switchmaterial.SwitchFragment;
4141
import io.material.catalog.tabs.TabsFragment;
4242
import io.material.catalog.textfield.TextFieldFragment;
43+
import io.material.catalog.themeswitcher.ThemeAttributeValuesCreator;
4344
import io.material.catalog.themeswitcher.ThemeSwitcherDialogFragment;
4445
import io.material.catalog.themeswitcher.ThemeSwitcherResourceProvider;
4546
import io.material.catalog.timepicker.TimePickerDemoLandingFragment;
@@ -92,4 +93,9 @@ static TocResourceProvider provideTocResourceProvider() {
9293
static ThemeSwitcherResourceProvider provideThemeSwitcherResourceProvider() {
9394
return new ThemeSwitcherResourceProvider();
9495
}
96+
97+
@Provides
98+
static ThemeAttributeValuesCreator provideThemeAttributeValuesCreator() {
99+
return new ThemeAttributeValuesCreator();
100+
}
95101
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
* Copyright 2018 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.material.catalog.themeswitcher;
18+
19+
import io.material.catalog.R;
20+
21+
import android.annotation.SuppressLint;
22+
import android.content.Context;
23+
import android.content.res.ColorStateList;
24+
import android.content.res.TypedArray;
25+
import android.graphics.Color;
26+
import androidx.core.view.MarginLayoutParamsCompat;
27+
import androidx.core.widget.CompoundButtonCompat;
28+
import androidx.appcompat.widget.AppCompatRadioButton;
29+
import android.widget.LinearLayout;
30+
import androidx.annotation.ColorInt;
31+
import androidx.annotation.NonNull;
32+
import androidx.annotation.StyleRes;
33+
import androidx.annotation.StyleableRes;
34+
35+
/**
36+
* Theme switcher dialog that allows the user to change different theming aspects like colors and
37+
* shapes. Each group in the dialog has a set of possible style values that are used as theme
38+
* overlays, overriding attributes in the base theme like shape appearances or color attributes.
39+
*/
40+
public class ThemeAttributeValuesCreator {
41+
42+
@NonNull
43+
public ThemeAttributeValues createColorPalette(
44+
@NonNull Context context,
45+
@StyleRes int themeOverlay,
46+
@NonNull @StyleableRes int[] themeOverlayAttrs) {
47+
return new ColorPalette(context, themeOverlay, themeOverlayAttrs);
48+
}
49+
50+
@NonNull
51+
public ThemeAttributeValues createThemeAttributeValuesWithContentDescription(
52+
@StyleRes int themeOverlay, @NonNull String contentDescription) {
53+
return new ThemeAttributeValuesWithContentDescription(themeOverlay, contentDescription);
54+
}
55+
56+
@NonNull
57+
public ThemeAttributeValues createThemeAttributeValues(
58+
@StyleRes int themeOverlay) {
59+
return new ThemeAttributeValues(themeOverlay);
60+
}
61+
62+
/**
63+
* Class for customizing radio buttons in the theme switcher.
64+
*/
65+
public static class ThemeAttributeValues {
66+
@StyleRes final int themeOverlay;
67+
68+
@SuppressLint("ResourceType")
69+
public ThemeAttributeValues(@StyleRes int themeOverlay) {
70+
this.themeOverlay = themeOverlay;
71+
}
72+
73+
public void customizeRadioButton(@NonNull AppCompatRadioButton button) {}
74+
}
75+
76+
private static class ThemeAttributeValuesWithContentDescription extends ThemeAttributeValues {
77+
private final String contentDescription;
78+
79+
@SuppressLint("ResourceType")
80+
public ThemeAttributeValuesWithContentDescription(
81+
@StyleRes int themeOverlay, @NonNull String contentDescription) {
82+
super(themeOverlay);
83+
this.contentDescription = contentDescription;
84+
}
85+
86+
@Override
87+
public void customizeRadioButton(@NonNull AppCompatRadioButton button) {
88+
button.setText(contentDescription);
89+
LinearLayout.LayoutParams size =
90+
new LinearLayout.LayoutParams(
91+
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
92+
MarginLayoutParamsCompat.setMarginEnd(
93+
size, button.getResources().getDimensionPixelSize(R.dimen.theme_switcher_radio_spacing));
94+
button.setLayoutParams(size);
95+
}
96+
}
97+
98+
private class ColorPalette extends ThemeAttributeValues {
99+
@ColorInt private final int main;
100+
101+
@SuppressLint("ResourceType")
102+
public ColorPalette(
103+
Context context,
104+
@StyleRes int themeOverlay,
105+
@NonNull @StyleableRes int[] themeOverlayAttrs) {
106+
super(themeOverlay);
107+
TypedArray a = context.obtainStyledAttributes(themeOverlay, themeOverlayAttrs);
108+
main = a.getColor(0, Color.TRANSPARENT);
109+
110+
a.recycle();
111+
}
112+
113+
@Override
114+
public void customizeRadioButton(@NonNull AppCompatRadioButton button) {
115+
CompoundButtonCompat.setButtonTintList(
116+
button, ColorStateList.valueOf(convertToDisplay(main)));
117+
}
118+
119+
@ColorInt
120+
private int convertToDisplay(@ColorInt int color) {
121+
return color == Color.WHITE ? Color.BLACK : color;
122+
}
123+
}
124+
}

catalog/java/io/material/catalog/themeswitcher/ThemeSwitcherDialogFragment.java

Lines changed: 8 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,17 @@
1818

1919
import io.material.catalog.R;
2020

21-
import android.annotation.SuppressLint;
2221
import android.app.Dialog;
2322
import android.content.Context;
24-
import android.content.res.ColorStateList;
2523
import android.content.res.TypedArray;
26-
import android.graphics.Color;
2724
import android.os.Bundle;
28-
import androidx.core.view.MarginLayoutParamsCompat;
29-
import androidx.core.widget.CompoundButtonCompat;
3025
import androidx.appcompat.widget.AppCompatRadioButton;
3126
import android.view.LayoutInflater;
3227
import android.view.View;
3328
import android.view.ViewGroup;
34-
import android.widget.LinearLayout;
3529
import android.widget.RadioGroup;
3630
import android.widget.TextView;
3731
import androidx.annotation.ArrayRes;
38-
import androidx.annotation.ColorInt;
3932
import androidx.annotation.IdRes;
4033
import androidx.annotation.NonNull;
4134
import androidx.annotation.Nullable;
@@ -48,6 +41,7 @@
4841
import dagger.android.DispatchingAndroidInjector;
4942
import dagger.android.HasAndroidInjector;
5043
import dagger.android.support.AndroidSupportInjection;
44+
import io.material.catalog.themeswitcher.ThemeAttributeValuesCreator.ThemeAttributeValues;
5145
import io.material.catalog.windowpreferences.WindowPreferencesManager;
5246
import javax.inject.Inject;
5347

@@ -77,6 +71,7 @@ private enum ThemingType {
7771
}
7872

7973
@Inject ThemeSwitcherResourceProvider resourceProvider;
74+
@Inject ThemeAttributeValuesCreator themeAttributeValuesCreator;
8075
private RadioGroup primaryColorGroup;
8176
private RadioGroup secondaryColorGroup;
8277
private RadioGroup shapeCornerFamilyGroup;
@@ -251,14 +246,17 @@ private void initializeThemingValues(
251246
// Create RadioButtons for themeAttributeValues values
252247
switch (themingType) {
253248
case COLOR:
254-
themeAttributeValues = new ColorPalette(valueThemeOverlay, themeOverlayAttrs);
249+
themeAttributeValues =
250+
themeAttributeValuesCreator.createColorPalette(
251+
getContext(), valueThemeOverlay, themeOverlayAttrs);
255252
break;
256253
case SHAPE_CORNER_FAMILY:
257-
themeAttributeValues = new ThemeAttributeValues(valueThemeOverlay);
254+
themeAttributeValues =
255+
themeAttributeValuesCreator.createThemeAttributeValues(valueThemeOverlay);
258256
break;
259257
case SHAPE_CORNER_SIZE:
260258
themeAttributeValues =
261-
new ThemeAttributeValuesWithContentDescription(
259+
themeAttributeValuesCreator.createThemeAttributeValuesWithContentDescription(
262260
valueThemeOverlay, contentDescriptionArray.getString(i));
263261
break;
264262
}
@@ -291,63 +289,6 @@ private AppCompatRadioButton createCompatRadioButton(
291289
return button;
292290
}
293291

294-
private static class ThemeAttributeValues {
295-
@StyleRes private final int themeOverlay;
296-
297-
@SuppressLint("ResourceType")
298-
public ThemeAttributeValues(@StyleRes int themeOverlay) {
299-
this.themeOverlay = themeOverlay;
300-
}
301-
302-
public void customizeRadioButton(AppCompatRadioButton button) {}
303-
}
304-
305-
private static class ThemeAttributeValuesWithContentDescription extends ThemeAttributeValues {
306-
private final String contentDescription;
307-
308-
@SuppressLint("ResourceType")
309-
public ThemeAttributeValuesWithContentDescription(
310-
@StyleRes int themeOverlay, String contentDescription) {
311-
super(themeOverlay);
312-
this.contentDescription = contentDescription;
313-
}
314-
315-
@Override
316-
public void customizeRadioButton(AppCompatRadioButton button) {
317-
button.setText(contentDescription);
318-
LinearLayout.LayoutParams size =
319-
new LinearLayout.LayoutParams(
320-
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
321-
MarginLayoutParamsCompat.setMarginEnd(
322-
size, button.getResources().getDimensionPixelSize(R.dimen.theme_switcher_radio_spacing));
323-
button.setLayoutParams(size);
324-
}
325-
}
326-
327-
private class ColorPalette extends ThemeAttributeValues {
328-
@ColorInt private final int main;
329-
330-
@SuppressLint("ResourceType")
331-
public ColorPalette(@StyleRes int themeOverlay, @StyleableRes int[] themeOverlayAttrs) {
332-
super(themeOverlay);
333-
TypedArray a = getContext().obtainStyledAttributes(themeOverlay, themeOverlayAttrs);
334-
main = a.getColor(0, Color.TRANSPARENT);
335-
336-
a.recycle();
337-
}
338-
339-
@Override
340-
public void customizeRadioButton(AppCompatRadioButton button) {
341-
CompoundButtonCompat.setButtonTintList(
342-
button, ColorStateList.valueOf(convertToDisplay(main)));
343-
}
344-
345-
@ColorInt
346-
private int convertToDisplay(@ColorInt int color) {
347-
return color == Color.WHITE ? Color.BLACK : color;
348-
}
349-
}
350-
351292
@Inject DispatchingAndroidInjector<Object> childFragmentInjector;
352293

353294
@Override

0 commit comments

Comments
 (0)