Custom Theme 8/n: add color step screen
Bug: 124796742
Change-Id: I4944a74f49e672783d373c0197b6f296916963b6
diff --git a/res/drawable/color_chip.xml b/res/drawable/color_chip.xml
new file mode 100644
index 0000000..bc09992
--- /dev/null
+++ b/res/drawable/color_chip.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:state_activated="true"
+ android:drawable="@drawable/color_chip_filled" />
+ <item
+ android:state_activated="false"
+ android:drawable="@drawable/color_chip_hollow" />
+ <item
+ android:drawable="@drawable/color_chip_hollow"/>
+</selector>
\ No newline at end of file
diff --git a/res/drawable/color_chip_filled.xml b/res/drawable/color_chip_filled.xml
new file mode 100644
index 0000000..34ef0ef
--- /dev/null
+++ b/res/drawable/color_chip_filled.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval">
+ <size
+ android:width="@dimen/component_color_chip_size"
+ android:height="@dimen/component_color_chip_size" />
+ <solid android:color="@android:color/black" />
+</shape>
diff --git a/res/drawable/color_chip_hollow.xml b/res/drawable/color_chip_hollow.xml
new file mode 100644
index 0000000..76ab6b8
--- /dev/null
+++ b/res/drawable/color_chip_hollow.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="ring"
+ android:innerRadius="13dp"
+ android:thickness="8dp"
+ android:useLevel="false">
+ <solid android:color="@android:color/black"/>
+</shape>
diff --git a/res/layout/theme_color_option.xml b/res/layout/theme_color_option.xml
new file mode 100644
index 0000000..fbede9f
--- /dev/null
+++ b/res/layout/theme_color_option.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_marginHorizontal="10dp">
+
+ <ImageView
+ android:id="@+id/option_tile"
+ android:layout_width="@dimen/component_color_chip_size"
+ android:layout_height="@dimen/component_color_chip_size"
+ android:layout_gravity="center"
+ android:src="@drawable/color_chip"/>
+</FrameLayout>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index d940e7c..d76236d 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -74,4 +74,6 @@
<dimen name="font_comonent_option_thumbnail_size">32dp</dimen>
<dimen name="component_icon_thumb_size">40dp</dimen>
+
+ <dimen name="component_color_chip_size">42dp</dimen>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index ca56f83..e04fd0f 100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -119,6 +119,9 @@
<!-- Title of a page allowing the user to choose an icon set for a custom theme -->
<string name="icon_component_title">Choose icons</string>
+ <!-- Title of a page allowing the user to choose a color for a custom theme -->
+ <string name="color_component_title">Choose color</string>
+
<!-- Title of a set of icons that the user can chose for their custom style (eg, "Icons 2") -->
<string name="icon_component_label">Icons <xliff:g name="component_number" example="1">%1$d</xliff:g></string>
diff --git a/src/com/android/customization/model/ResourceConstants.java b/src/com/android/customization/model/ResourceConstants.java
index 3b831b3..8a3e436 100644
--- a/src/com/android/customization/model/ResourceConstants.java
+++ b/src/com/android/customization/model/ResourceConstants.java
@@ -16,6 +16,7 @@
package com.android.customization.model;
import android.content.Context;
+import android.content.res.Resources;
import android.provider.Settings.Secure;
import com.android.wallpaper.R;
@@ -60,6 +61,11 @@
String OVERLAY_CATEGORY_ICON_LAUNCHER = "android.theme.customization.icon_pack.launcher";
/**
+ * Global Android theme category (default theme prebundled with the OS)
+ */
+ String OVERLAY_CATEGORY_ANDROID_THEME = "android.theme";
+
+ /**
* Secure Setting used to store the currently set theme.
*/
String THEME_SETTING = Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES;
@@ -75,6 +81,10 @@
};
ArrayList<String> sTargetPackages = new ArrayList<>();
+ String ACCENT_COLOR_LIGHT_NAME = "accent_device_default_light";
+ String ACCENT_COLOR_DARK_NAME = "accent_device_default_dark";
+
+ float PATH_SIZE = 100f;
static String[] getPackagesToOverlay(Context context) {
if (sTargetPackages.isEmpty()) {
@@ -88,4 +98,11 @@
static String getLauncherPackage(Context context) {
return context.getString(R.string.launcher_overlayable_package);
}
+
+ /**
+ * @return the value CONFIG_ICON_MASK for the given package name using the given Resources
+ */
+ static String getIconMask(Resources res, String packageName) {
+ return res.getString(res.getIdentifier(CONFIG_ICON_MASK, "string", packageName));
+ }
}
diff --git a/src/com/android/customization/model/theme/DefaultThemeProvider.java b/src/com/android/customization/model/theme/DefaultThemeProvider.java
index 28af9ea..510b5e7 100644
--- a/src/com/android/customization/model/theme/DefaultThemeProvider.java
+++ b/src/com/android/customization/model/theme/DefaultThemeProvider.java
@@ -15,6 +15,8 @@
*/
package com.android.customization.model.theme;
+import static com.android.customization.model.ResourceConstants.ACCENT_COLOR_DARK_NAME;
+import static com.android.customization.model.ResourceConstants.ACCENT_COLOR_LIGHT_NAME;
import static com.android.customization.model.ResourceConstants.ANDROID_PACKAGE;
import static com.android.customization.model.ResourceConstants.CONFIG_ICON_MASK;
import static com.android.customization.model.ResourceConstants.ICON_PREVIEW_DRAWABLE_NAME;
@@ -87,8 +89,6 @@
private static final String DEFAULT_THEME_NAME= "default";
- private static final String ACCENT_COLOR_LIGHT_NAME = "accent_device_default_light";
- private static final String ACCENT_COLOR_DARK_NAME = "accent_device_default_dark";
// List of packages
private final String[] mShapePreviewIconPackages;
private List<ThemeBundle> mThemes;
diff --git a/src/com/android/customization/model/theme/ThemeBundle.java b/src/com/android/customization/model/theme/ThemeBundle.java
index 8c78239..8e5061d 100644
--- a/src/com/android/customization/model/theme/ThemeBundle.java
+++ b/src/com/android/customization/model/theme/ThemeBundle.java
@@ -15,6 +15,8 @@
*/
package com.android.customization.model.theme;
+import static com.android.customization.model.ResourceConstants.PATH_SIZE;
+
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -38,6 +40,7 @@
import com.android.customization.model.CustomizationManager;
import com.android.customization.model.CustomizationOption;
import com.android.customization.widget.DynamicAdaptiveIconDrawable;
+import com.android.customization.model.ResourceConstants;
import com.android.wallpaper.R;
import com.android.wallpaper.asset.Asset;
import com.android.wallpaper.asset.ResourceAsset;
@@ -195,7 +198,6 @@
}
public static class Builder {
- private static final float PATH_SIZE = 100f;
protected String mTitle;
private Typeface mBodyFontFamily;
private Typeface mHeadlineFontFamily;
diff --git a/src/com/android/customization/model/theme/custom/ColorOptionsProvider.java b/src/com/android/customization/model/theme/custom/ColorOptionsProvider.java
new file mode 100644
index 0000000..3603533
--- /dev/null
+++ b/src/com/android/customization/model/theme/custom/ColorOptionsProvider.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.customization.model.theme.custom;
+
+import static com.android.customization.model.ResourceConstants.ACCENT_COLOR_DARK_NAME;
+import static com.android.customization.model.ResourceConstants.ACCENT_COLOR_LIGHT_NAME;
+import static com.android.customization.model.ResourceConstants.ANDROID_PACKAGE;
+import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ANDROID_THEME;
+import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_COLOR;
+import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SYSUI;
+import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_SHAPE;
+import static com.android.customization.model.ResourceConstants.PATH_SIZE;
+import static com.android.customization.model.ResourceConstants.SYSUI_ICONS_FOR_PREVIEW;
+import static com.android.customization.model.ResourceConstants.SYSUI_PACKAGE;
+import static com.android.customization.model.theme.custom.ThemeComponentOption.ColorOption.COLOR_TILES_ICON_IDS;
+
+import android.content.Context;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.PathShape;
+import android.os.UserHandle;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.core.graphics.PathParser;
+
+import com.android.customization.model.ResourceConstants;
+import com.android.customization.model.theme.OverlayManagerCompat;
+import com.android.customization.model.theme.custom.ThemeComponentOption.ColorOption;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Implementation of {@link ThemeComponentOptionProvider} that reads {@link ColorOption}s from
+ * icon overlays.
+ */
+public class ColorOptionsProvider extends ThemeComponentOptionProvider<ColorOption> {
+
+ private static final String TAG = "ColorOptionsProvider";
+ private final CustomThemeManager mCustomThemeManager;
+ private final String mDefaultThemePackage;
+
+ public ColorOptionsProvider(Context context, OverlayManagerCompat manager,
+ CustomThemeManager customThemeManager) {
+ super(context, manager, OVERLAY_CATEGORY_COLOR);
+ mCustomThemeManager = customThemeManager;
+ // System color is set with a static overlay for android.theme category, so let's try to
+ // find that first, and if that's not present, we'll default to System resources.
+ // (see #addDefault())
+ List<String> themePackages = manager.getOverlayPackagesForCategory(
+ OVERLAY_CATEGORY_ANDROID_THEME, UserHandle.myUserId(), ANDROID_PACKAGE);
+ mDefaultThemePackage = themePackages.isEmpty() ? null : themePackages.get(0);
+ }
+
+ @Override
+ protected void loadOptions() {
+ List<Drawable> previewIcons = new ArrayList<>();
+ String iconPackage =
+ mCustomThemeManager.getOverlayPackages().get(OVERLAY_CATEGORY_ICON_SYSUI);
+ if (TextUtils.isEmpty(iconPackage)) {
+ iconPackage = SYSUI_PACKAGE;
+ }
+ for (String iconName : SYSUI_ICONS_FOR_PREVIEW) {
+ try {
+ if (previewIcons.size() == COLOR_TILES_ICON_IDS.length) {
+ break;
+ }
+ previewIcons.add(loadIconPreviewDrawable(iconName, iconPackage));
+ } catch (NameNotFoundException | NotFoundException e) {
+ Log.w(TAG, String.format("Couldn't load icon in %s for color preview, will skip it",
+ iconPackage), e);
+ }
+ }
+ String shapePackage = mCustomThemeManager.getOverlayPackages().get(OVERLAY_CATEGORY_SHAPE);
+ if (TextUtils.isEmpty(shapePackage)) {
+ shapePackage = ANDROID_PACKAGE;
+ }
+ Drawable shape = loadShape(shapePackage);
+ addDefault(previewIcons, shape);
+ for (String overlayPackage : mOverlayPackages) {
+ try {
+ Resources overlayRes = getOverlayResources(overlayPackage);
+ int lightColor = overlayRes.getColor(
+ overlayRes.getIdentifier(ACCENT_COLOR_LIGHT_NAME, "color", overlayPackage),
+ null);
+ int darkColor = overlayRes.getColor(
+ overlayRes.getIdentifier(ACCENT_COLOR_DARK_NAME, "color", overlayPackage),
+ null);
+
+ ColorOption option = new ColorOption(overlayPackage, lightColor, darkColor);
+ option.setPreviewIcons(previewIcons);
+ option.setShapeDrawable(shape);
+ mOptions.add(option);
+ } catch (NameNotFoundException | NotFoundException e) {
+ Log.w(TAG, String.format("Couldn't load color overlay %s, will skip it",
+ overlayPackage), e);
+ }
+ }
+ }
+
+ private void addDefault(List<Drawable> previewIcons, Drawable shape) {
+ int lightColor, darkColor;
+ Resources system = Resources.getSystem();
+ try {
+ Resources r = getOverlayResources(mDefaultThemePackage);
+ lightColor = r.getColor(
+ r.getIdentifier(ACCENT_COLOR_LIGHT_NAME, "color", mDefaultThemePackage),
+ null);
+ darkColor = r.getColor(
+ r.getIdentifier(ACCENT_COLOR_DARK_NAME, "color", mDefaultThemePackage),
+ null);
+ } catch (NotFoundException | NameNotFoundException e) {
+ Log.d(TAG, "Didn't find default color, will use system option", e);
+
+ lightColor = system.getColor(
+ system.getIdentifier(ACCENT_COLOR_LIGHT_NAME, "color", ANDROID_PACKAGE), null);
+
+ darkColor = system.getColor(
+ system.getIdentifier(ACCENT_COLOR_DARK_NAME, "color", ANDROID_PACKAGE), null);
+ }
+ ColorOption option = new ColorOption(null, lightColor, darkColor);
+ option.setPreviewIcons(previewIcons);
+ option.setShapeDrawable(shape);
+ mOptions.add(option);
+ }
+
+ private Drawable loadIconPreviewDrawable(String drawableName, String packageName)
+ throws NameNotFoundException, NotFoundException {
+
+ Resources overlayRes = getOverlayResources(packageName);
+ return overlayRes.getDrawable(
+ overlayRes.getIdentifier(drawableName, "drawable", packageName), null);
+ }
+
+ private Drawable loadShape(String packageName) {
+ String path = null;
+ try {
+ Resources r = getOverlayResources(packageName);
+
+ path = ResourceConstants.getIconMask(r, packageName);
+ } catch (NameNotFoundException e) {
+ Log.d(TAG, String.format("Couldn't load shape icon for %s, skipping.", packageName), e);
+ }
+ ShapeDrawable shapeDrawable = null;
+ if (!TextUtils.isEmpty(path)) {
+ PathShape shape = new PathShape(PathParser.createPathFromPathData(path),
+ PATH_SIZE, PATH_SIZE);
+ shapeDrawable = new ShapeDrawable(shape);
+ shapeDrawable.setIntrinsicHeight((int) PATH_SIZE);
+ shapeDrawable.setIntrinsicWidth((int) PATH_SIZE);
+ }
+ return shapeDrawable;
+ }
+
+}
diff --git a/src/com/android/customization/model/theme/custom/ThemeComponentOption.java b/src/com/android/customization/model/theme/custom/ThemeComponentOption.java
index 352b0e7..f3cf7cc 100644
--- a/src/com/android/customization/model/theme/custom/ThemeComponentOption.java
+++ b/src/com/android/customization/model/theme/custom/ThemeComponentOption.java
@@ -21,15 +21,23 @@
import static com.android.customization.model.ResourceConstants.SYSUI_ICONS_FOR_PREVIEW;
import android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.CompoundButton;
import android.widget.ImageView;
+import android.widget.SeekBar;
+import android.widget.Switch;
import android.widget.TextView;
+import androidx.annotation.ColorInt;
+import androidx.annotation.Nullable;
+
import com.android.customization.model.CustomizationManager;
import com.android.customization.model.CustomizationOption;
import com.android.customization.model.ResourceConstants;
@@ -46,6 +54,8 @@
* shape, etc).
* Extending classes correspond to each component's options and provide the structure to bind
* preview and thumbnails.
+ * // TODO (santie): refactor the logic to bind preview cards to reuse between ThemeFragment and
+ * // here
*/
public abstract class ThemeComponentOption implements CustomizationOption<ThemeComponentOption> {
@@ -199,28 +209,129 @@
public static class ColorOption extends ThemeComponentOption {
- ColorOption(String packageName) {
+ /**
+ * Ids of views used to represent quick setting tiles in the color preview screen
+ */
+ private static int[] COLOR_TILE_IDS = {
+ R.id.preview_color_qs_0_bg, R.id.preview_color_qs_1_bg, R.id.preview_color_qs_2_bg
+ };
+ static int[] COLOR_TILES_ICON_IDS = {
+ R.id.preview_color_qs_0_icon, R.id.preview_color_qs_1_icon,
+ R.id.preview_color_qs_2_icon
+ };
+
+ /**
+ * Ids of views used to represent control buttons in the color preview screen
+ */
+ private static int[] COLOR_BUTTON_IDS = {
+ R.id.preview_check_selected, R.id.preview_radio_selected,
+ R.id.preview_toggle_selected,
+ };
+
+ @ColorInt private int mColorAccentLight;
+ @ColorInt private int mColorAccentDark;
+ /**
+ * Icons shown as example of QuickSettings tiles in the color preview screen.
+ */
+ private List<Drawable> mIcons = new ArrayList<>();
+
+ /**
+ * Drawable with the currently selected shape to be used as background of the sample
+ * QuickSetting icons in the color preview screen.
+ */
+ private Drawable mShapeDrawable;
+
+ ColorOption(String packageName, @ColorInt int lightColor,
+ @ColorInt int darkColor) {
addOverlayPackage(OVERLAY_CATEGORY_COLOR, packageName);
+ mColorAccentLight = lightColor;
+ mColorAccentDark = darkColor;
}
@Override
public void bindThumbnailTile(View view) {
+ int color = resolveColor(view.getResources());
+ ((ImageView) view.findViewById(R.id.option_tile)).getDrawable().setTint(color);
+ }
+ private int resolveColor(Resources res) {
+ Configuration configuration = res.getConfiguration();
+ return (configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK)
+ == Configuration.UI_MODE_NIGHT_YES ? mColorAccentDark : mColorAccentLight;
}
@Override
public boolean isActive(CustomizationManager<ThemeComponentOption> manager) {
- return false;
+ CustomThemeManager customThemeManager = (CustomThemeManager) manager;
+ return Objects.equals(getOverlayPackages().get(OVERLAY_CATEGORY_COLOR),
+ customThemeManager.getOverlayPackages().get(OVERLAY_CATEGORY_COLOR));
}
@Override
public int getLayoutResId() {
- return 0;
+ return R.layout.theme_color_option;
}
@Override
public void bindPreview(ViewGroup container) {
+ TextView header = container.findViewById(R.id.theme_preview_card_header);
+ header.setText(R.string.preview_name_color);
+ header.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_colorize_24px, 0, 0);
+ ViewGroup cardBody = container.findViewById(R.id.theme_preview_card_body_container);
+ if (cardBody.getChildCount() == 0) {
+ LayoutInflater.from(container.getContext()).inflate(
+ R.layout.preview_card_color_content, cardBody, true);
+ }
+ @ColorInt int accentColor = resolveColor(container.getResources());
+ ColorStateList tintList = new ColorStateList(
+ new int[][]{
+ new int[]{android.R.attr.state_selected},
+ new int[]{android.R.attr.state_checked}
+ },
+ new int[] {
+ accentColor,
+ accentColor
+ }
+ );
+
+ for (int i = 0; i < COLOR_BUTTON_IDS.length; i++) {
+ CompoundButton button = container.findViewById(COLOR_BUTTON_IDS[i]);
+ button.setButtonTintList(tintList);
+ }
+
+ Switch toggle = container.findViewById(R.id.preview_toggle_selected);
+ toggle.setThumbTintList(tintList);
+ toggle.setTrackTintList(tintList);
+
+ ColorStateList seekbarTintList = ColorStateList.valueOf(accentColor);
+ SeekBar seekbar = container.findViewById(R.id.preview_seekbar);
+ seekbar.setThumbTintList(seekbarTintList);
+ seekbar.setProgressTintList(seekbarTintList);
+ seekbar.setProgressBackgroundTintList(seekbarTintList);
+ // Disable seekbar
+ seekbar.setOnTouchListener((view, motionEvent) -> true);
+ if (!mIcons.isEmpty() && mShapeDrawable != null) {
+ for (int i = 0; i < COLOR_TILE_IDS.length; i++) {
+ Drawable icon = mIcons.get(i).getConstantState().newDrawable();
+ //TODO: load and set the shape.
+ Drawable bgShape = mShapeDrawable.getConstantState().newDrawable();
+ bgShape.setTint(accentColor);
+
+ ImageView bg = container.findViewById(COLOR_TILE_IDS[i]);
+ bg.setImageDrawable(bgShape);
+ ImageView fg = container.findViewById(COLOR_TILES_ICON_IDS[i]);
+ fg.setImageDrawable(icon);
+ }
+ }
+ }
+
+ public void setPreviewIcons(List<Drawable> icons) {
+ mIcons.addAll(icons);
+ }
+
+ public void setShapeDrawable(@Nullable Drawable shapeDrawable) {
+ mShapeDrawable = shapeDrawable;
}
}
diff --git a/src/com/android/customization/picker/theme/CustomThemeActivity.java b/src/com/android/customization/picker/theme/CustomThemeActivity.java
index 0fd2b6b..50a3534 100644
--- a/src/com/android/customization/picker/theme/CustomThemeActivity.java
+++ b/src/com/android/customization/picker/theme/CustomThemeActivity.java
@@ -34,11 +34,13 @@
import com.android.customization.model.theme.ThemeBundle.Builder;
import com.android.customization.model.theme.ThemeBundleProvider;
import com.android.customization.model.theme.ThemeManager;
+import com.android.customization.model.theme.custom.ColorOptionsProvider;
import com.android.customization.model.theme.custom.CustomTheme;
import com.android.customization.model.theme.custom.CustomThemeManager;
import com.android.customization.model.theme.custom.FontOptionsProvider;
import com.android.customization.model.theme.custom.IconOptionsProvider;
import com.android.customization.model.theme.custom.ThemeComponentOption;
+import com.android.customization.model.theme.custom.ThemeComponentOption.ColorOption;
import com.android.customization.model.theme.custom.ThemeComponentOption.FontOption;
import com.android.customization.model.theme.custom.ThemeComponentOption.IconOption;
import com.android.customization.model.theme.custom.ThemeComponentOptionProvider;
@@ -128,8 +130,10 @@
private void initSteps() {
mSteps = new ArrayList<>();
OverlayManagerCompat manager = new OverlayManagerCompat(this);
- mSteps.add(new FontStep(new FontOptionsProvider(this, manager), 0, 2));
- mSteps.add(new IconStep(new IconOptionsProvider(this, manager), 1, 2));
+ mSteps.add(new FontStep(new FontOptionsProvider(this, manager), 0, 3));
+ mSteps.add(new IconStep(new IconOptionsProvider(this, manager), 1, 3));
+ mSteps.add(new ColorStep(new ColorOptionsProvider(this, manager, mCustomThemeManager),
+ 2, 3));
mCurrentStep = 0;
}
@@ -278,4 +282,21 @@
titleResId);
}
}
+
+ private class ColorStep extends ComponentStep<ColorOption> {
+
+ protected ColorStep(ThemeComponentOptionProvider<ColorOption> provider,
+ int position, int totalSteps) {
+ super(R.string.color_component_title, provider, position, totalSteps);
+ }
+
+ @Override
+ CustomThemeComponentFragment createFragment() {
+ return CustomThemeComponentFragment.newInstance(
+ CustomThemeActivity.this.getString(R.string.custom_theme_fragment_title),
+ position,
+ totalSteps,
+ titleResId);
+ }
+ }
}