Add alternative checkmark for currently selected option
Bug: 181111177
Test: manual
Change-Id: I990b7a50860093ed5031db1772ab35e2239748c5
diff --git a/res/drawable/check_circle_grey_large.xml b/res/drawable/check_circle_grey_large.xml
new file mode 100644
index 0000000..16c5d94
--- /dev/null
+++ b/res/drawable/check_circle_grey_large.xml
@@ -0,0 +1,31 @@
+<!--
+ Copyright (C) 2021 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.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <shape android:shape="oval">
+ <size android:width="@dimen/center_check_size"
+ android:height="@dimen/center_check_size" />
+ <solid android:color="@color/center_check_color" />
+ </shape>
+ </item>
+ <item>
+ <inset android:drawable="@drawable/ic_check_24dp"
+ android:insetTop="@dimen/center_check_padding"
+ android:insetRight="@dimen/center_check_padding"
+ android:insetBottom="@dimen/center_check_padding"
+ android:insetLeft="@dimen/center_check_padding"/>
+ </item>
+</layer-list>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 02b3472..1f1ee30 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -52,4 +52,6 @@
<color name="divider_color">@color/black_14_alpha</color>
<color name="cover_title_color">@color/black_87_alpha</color>
+
+ <color name="center_check_color">#EDF2EB</color>
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 53b4e39..abc2c6a 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -22,6 +22,8 @@
<dimen name="tip_dot_line_width">2dp</dimen>
<dimen name="check_size">16dp</dimen>
+ <dimen name="center_check_size">34dp</dimen>
+ <dimen name="center_check_padding">9dp</dimen>
<dimen name="check_offset">4dp</dimen>
<dimen name="component_preview_page_bottom_margin">16dp</dimen>
diff --git a/src/com/android/customization/module/CustomizationInjector.java b/src/com/android/customization/module/CustomizationInjector.java
index fe5a0aa..722ebb3 100644
--- a/src/com/android/customization/module/CustomizationInjector.java
+++ b/src/com/android/customization/module/CustomizationInjector.java
@@ -56,7 +56,7 @@
*
* @return {@code true} if the system supports customization extension, {@code false} otherwise.
*/
- default boolean supportsCustomizationExtended() {
+ default boolean supportsCustomizationExtended(Context context) {
return false;
}
}
diff --git a/src/com/android/customization/picker/CustomizationPickerActivity.java b/src/com/android/customization/picker/CustomizationPickerActivity.java
index 17b4fc7..b54d24c 100644
--- a/src/com/android/customization/picker/CustomizationPickerActivity.java
+++ b/src/com/android/customization/picker/CustomizationPickerActivity.java
@@ -241,7 +241,7 @@
private boolean supportsCustomizationExtended() {
CustomizationInjector injector = (CustomizationInjector) InjectorProvider.getInjector();
- return injector.supportsCustomizationExtended();
+ return injector.supportsCustomizationExtended(this);
}
private void initSections() {
diff --git a/src/com/android/customization/picker/theme/CustomThemeComponentFragment.java b/src/com/android/customization/picker/theme/CustomThemeComponentFragment.java
index 5495e9a..a1e9967 100644
--- a/src/com/android/customization/picker/theme/CustomThemeComponentFragment.java
+++ b/src/com/android/customization/picker/theme/CustomThemeComponentFragment.java
@@ -27,6 +27,7 @@
import com.android.customization.model.theme.custom.ThemeComponentOption;
import com.android.customization.model.theme.custom.ThemeComponentOptionProvider;
import com.android.customization.widget.OptionSelectorController;
+import com.android.customization.widget.OptionSelectorController.CheckmarkStyle;
import com.android.wallpaper.R;
import com.android.wallpaper.picker.AppbarFragment;
@@ -94,7 +95,7 @@
private void setUpOptions() {
mProvider.fetch(options -> {
mOptionsController = new OptionSelectorController(
- mOptionsContainer, options, mUseGridLayout, false);
+ mOptionsContainer, options, mUseGridLayout, CheckmarkStyle.NONE);
mOptionsController.addListener(selected -> {
mSelectedOption = (ThemeComponentOption) selected;
diff --git a/src/com/android/customization/widget/OptionSelectorController.java b/src/com/android/customization/widget/OptionSelectorController.java
index 47b0aa7..1d1b658 100644
--- a/src/com/android/customization/widget/OptionSelectorController.java
+++ b/src/com/android/customization/widget/OptionSelectorController.java
@@ -29,6 +29,9 @@
import android.view.accessibility.AccessibilityEvent;
import android.widget.TextView;
+import androidx.annotation.ColorInt;
+import androidx.annotation.Dimension;
+import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
@@ -63,10 +66,17 @@
void onOptionSelected(CustomizationOption selected);
}
+ @IntDef({CheckmarkStyle.NONE, CheckmarkStyle.CORNER, CheckmarkStyle.CENTER})
+ public @interface CheckmarkStyle {
+ int NONE = 0;
+ int CORNER = 1;
+ int CENTER = 2;
+ }
+
private final RecyclerView mContainer;
private final List<T> mOptions;
private final boolean mUseGrid;
- private final boolean mShowCheckmark;
+ @CheckmarkStyle private final int mCheckmarkStyle;
private final Set<OptionSelectedListener> mListeners = new HashSet<>();
private RecyclerView.Adapter<TileViewHolder> mAdapter;
@@ -74,15 +84,15 @@
private CustomizationOption mAppliedOption;
public OptionSelectorController(RecyclerView container, List<T> options) {
- this(container, options, true, true);
+ this(container, options, true, CheckmarkStyle.CORNER);
}
public OptionSelectorController(RecyclerView container, List<T> options,
- boolean useGrid, boolean showCheckmark) {
+ boolean useGrid, @CheckmarkStyle int checkmarkStyle) {
mContainer = container;
mOptions = options;
mUseGrid = useGrid;
- mShowCheckmark = showCheckmark;
+ mCheckmarkStyle = checkmarkStyle;
}
public void addListener(OptionSelectedListener listener) {
@@ -132,14 +142,14 @@
if (holder instanceof TileViewHolder) {
TileViewHolder tileHolder = (TileViewHolder) holder;
if (isActivated) {
- if (option == mAppliedOption && mShowCheckmark) {
+ if (option == mAppliedOption && mCheckmarkStyle != CheckmarkStyle.NONE) {
tileHolder.setContentDescription(mContainer.getContext(), option,
R.string.option_applied_previewed_description);
} else {
tileHolder.setContentDescription(mContainer.getContext(), option,
R.string.option_previewed_description);
}
- } else if (option == mAppliedOption && mShowCheckmark) {
+ } else if (option == mAppliedOption && mCheckmarkStyle != CheckmarkStyle.NONE) {
tileHolder.setContentDescription(mContainer.getContext(), option,
R.string.option_applied_description);
} else {
@@ -195,40 +205,30 @@
if (holder.labelView != null) {
holder.labelView.setText(option.getTitle());
}
- option.bindThumbnailTile(holder.tileView);
holder.itemView.setActivated(option.equals(mSelectedOption));
+ option.bindThumbnailTile(holder.tileView);
holder.itemView.setOnClickListener(view -> setSelectedOption(option));
- if (mShowCheckmark && option.equals(mAppliedOption)) {
- Resources res = mContainer.getContext().getResources();
- Drawable checkmark = res.getDrawable(R.drawable.check_circle_accent_24dp,
- mContainer.getContext().getTheme());
- Drawable frame = holder.tileView.getForeground();
- Drawable[] layers = {frame, checkmark};
- if (frame == null) {
- layers = new Drawable[]{checkmark};
- }
- LayerDrawable checkedFrame = new LayerDrawable(layers);
-
- // Position at lower right
- int idx = layers.length - 1;
- int checkSize = (int) res.getDimension(R.dimen.check_size);
- int checkOffset = (int) res.getDimensionPixelOffset(R.dimen.check_offset);
- checkedFrame.setLayerGravity(idx, Gravity.BOTTOM | Gravity.RIGHT);
- checkedFrame.setLayerWidth(idx, checkSize);
- checkedFrame.setLayerHeight(idx, checkSize);
- checkedFrame.setLayerInsetBottom(idx, checkOffset);
- checkedFrame.setLayerInsetRight(idx, checkOffset);
- holder.tileView.setForeground(checkedFrame);
-
- // Initialize the currently applied option
- holder.setContentDescription(mContainer.getContext(), option,
- R.string.option_applied_previewed_description);
+ Resources res = mContainer.getContext().getResources();
+ if (mCheckmarkStyle == CheckmarkStyle.CORNER && option.equals(mAppliedOption)) {
+ drawCheckmark(option, holder,
+ res.getDrawable(R.drawable.check_circle_accent_24dp,
+ mContainer.getContext().getTheme()),
+ Gravity.BOTTOM | Gravity.RIGHT,
+ res.getDimensionPixelSize(R.dimen.check_size),
+ res.getDimensionPixelOffset(R.dimen.check_offset), 0);
+ } else if (mCheckmarkStyle == CheckmarkStyle.CENTER
+ && option.equals(mAppliedOption)) {
+ drawCheckmark(option, holder,
+ res.getDrawable(R.drawable.check_circle_grey_large,
+ mContainer.getContext().getTheme()),
+ Gravity.CENTER, res.getDimensionPixelSize(R.dimen.center_check_size),
+ 0, res.getColor(android.R.color.black));
} else if (option.equals(mAppliedOption)) {
// Initialize with "previewed" description if we don't show checkmark
holder.setContentDescription(mContainer.getContext(), option,
R.string.option_previewed_description);
- } else if (mShowCheckmark) {
+ } else if (mCheckmarkStyle != CheckmarkStyle.NONE) {
holder.tileView.setForeground(null);
}
}
@@ -237,6 +237,33 @@
public int getItemCount() {
return mOptions.size();
}
+
+ private void drawCheckmark(CustomizationOption<?> option, TileViewHolder holder,
+ Drawable checkmark, int gravity, @Dimension int checkSize,
+ @Dimension int checkOffset, @ColorInt int checkColor) {
+ if (checkColor != 0 && checkmark instanceof LayerDrawable) {
+ ((LayerDrawable) checkmark).getDrawable(1).setTint(checkColor);
+ }
+ Drawable frame = holder.tileView.getForeground();
+ Drawable[] layers = {frame, checkmark};
+ if (frame == null) {
+ layers = new Drawable[]{checkmark};
+ }
+ LayerDrawable checkedFrame = new LayerDrawable(layers);
+
+ // Position according to the given gravity and offset
+ int idx = layers.length - 1;
+ checkedFrame.setLayerGravity(idx, gravity);
+ checkedFrame.setLayerWidth(idx, checkSize);
+ checkedFrame.setLayerHeight(idx, checkSize);
+ checkedFrame.setLayerInsetBottom(idx, checkOffset);
+ checkedFrame.setLayerInsetRight(idx, checkOffset);
+ holder.tileView.setForeground(checkedFrame);
+
+ // Initialize the currently applied option
+ holder.setContentDescription(mContainer.getContext(), option,
+ R.string.option_applied_previewed_description);
+ }
};
Resources res = mContainer.getContext().getResources();