Custom Theme 6/n: edit custom theme
Add edit link from custom theme preview card, which takes
the user to CustomThemeAcitvity
Bug: 124796742
Change-Id: I5063ac73fd60b0dd12e993e5b07bdb69d0e9713a
diff --git a/res/drawable/ic_tune_24px.xml b/res/drawable/ic_tune_24px.xml
new file mode 100644
index 0000000..abad67c
--- /dev/null
+++ b/res/drawable/ic_tune_24px.xml
@@ -0,0 +1,24 @@
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M3,17v2h6v-2H3zM3,5v2h10V5H3zM13,21v-2h8v-2h-8v-2h-2v6H13zM7,9v2H3v2h4v2h2V9H7zM21,13v-2H11v2H21zM15,9h2V7h4V5h-4V3h-2V9z"/>
+</vector>
diff --git a/res/layout/theme_preview_card.xml b/res/layout/theme_preview_card.xml
index 18f2b15..77155f0 100644
--- a/res/layout/theme_preview_card.xml
+++ b/res/layout/theme_preview_card.xml
@@ -31,6 +31,7 @@
android:layout_height="match_parent"
android:padding="@dimen/preview_card_padding"
android:orientation="vertical">
+
<TextView
android:id="@+id/theme_preview_card_header"
android:layout_width="wrap_content"
@@ -39,11 +40,26 @@
android:layout_marginBottom="8dp"
android:drawablePadding="10dp"
android:textAppearance="@style/CardTitleTextAppearance"/>
+
<FrameLayout
android:id="@+id/theme_preview_card_body_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_marginHorizontal="8dp"/>
+ android:layout_marginHorizontal="8dp"
+ android:layout_weight="1"/>
+
+ <TextView
+ android:id="@+id/edit_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:drawableStart="@drawable/ic_tune_24px"
+ android:drawablePadding="8dp"
+ android:drawableTint="?android:colorAccent"
+ android:gravity="center"
+ android:text="@string/edit_custom_theme_lbl"
+ android:textAppearance="@style/EditLabelTextAppearance"
+ android:visibility="gone"/>
</LinearLayout>
</FrameLayout>
</androidx.cardview.widget.CardView>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 78a8f1f..d12735f 100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -38,6 +38,10 @@
[CHAR LIMIT=20] -->
<string name="apply_theme_btn">Apply</string>
+ <!-- Label telling the user they can tap the card to edit the currently selected custom Theme.
+ [CHAR LIMIT=50] -->
+ <string name="edit_custom_theme_lbl">Tap to edit</string>
+
<!-- Label for a checkbox to allow the user to use their currently set wallpaper instead of
the one bundled with selected Theme [CHAR LIMIT=35]-->
<string name="keep_my_wallpaper">Keep current wallpaper</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 18482ba..d53ffac 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -86,8 +86,9 @@
<item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault</item>
</style>
- <style name="ComponentCounterTextAppearance" parent="@android:style/TextAppearance.DeviceDefault.Small">
+ <style name="ComponentCounterTextAppearance" parent="@android:style/TextAppearance.DeviceDefault"/>
-
+ <style name="EditLabelTextAppearance" parent="@android:style/TextAppearance.DeviceDefault">
+ <item name="android:textColor">?android:colorAccent</item>
</style>
</resources>
diff --git a/src/com/android/customization/model/theme/DefaultThemeProvider.java b/src/com/android/customization/model/theme/DefaultThemeProvider.java
index 02a0047..4b5fb4a 100644
--- a/src/com/android/customization/model/theme/DefaultThemeProvider.java
+++ b/src/com/android/customization/model/theme/DefaultThemeProvider.java
@@ -413,8 +413,22 @@
new HashMap<>(), null));
return;
}
- Map<String, String> customPackages = new HashMap<>();
+ ThemeBundle.Builder builder = parseCustomTheme(serializedTheme);
+ if (builder != null) {
+ builder.setTitle(mContext.getString(R.string.custom_theme_title));
+ mThemes.add(builder.build());
+ } else {
+ Log.w(TAG, "Couldn't read stored custom theme, resetting");
+ mThemes.add(new CustomTheme(mContext.getString(R.string.custom_theme_title),
+ new HashMap<>(), null));
+ }
+ }
+
+ @Override
+ public Builder parseCustomTheme(String serializedTheme) {
try {
+ Map<String, String> customPackages = new HashMap<>();
+
JSONObject theme = new JSONObject(serializedTheme);
Iterator<String> keysIterator = theme.keys();
@@ -430,11 +444,10 @@
addNoPreviewIconOverlay(builder, customPackages.get(OVERLAY_CATEGORY_ICON_SETTINGS));
addNoPreviewIconOverlay(builder, customPackages.get(OVERLAY_CATEGORY_ICON_LAUNCHER));
- mThemes.add(builder.build());
+ return builder;
} catch (JSONException | NameNotFoundException | NotFoundException e) {
- Log.w(TAG, "Couldn't read stored custom theme, resetting", e);
- mThemes.add(new CustomTheme(mContext.getString(R.string.custom_theme_title),
- new HashMap<>(), null));
+ Log.i(TAG, "Couldn't parse serialized custom theme", e);
+ return null;
}
}
diff --git a/src/com/android/customization/model/theme/ThemeBundleProvider.java b/src/com/android/customization/model/theme/ThemeBundleProvider.java
index ba4ee5d..f2e1915 100644
--- a/src/com/android/customization/model/theme/ThemeBundleProvider.java
+++ b/src/com/android/customization/model/theme/ThemeBundleProvider.java
@@ -15,9 +15,13 @@
*/
package com.android.customization.model.theme;
+import androidx.annotation.Nullable;
+
import com.android.customization.model.CustomizationManager.OptionsFetchedListener;
+import com.android.customization.model.theme.ThemeBundle.Builder;
import com.android.customization.model.theme.custom.CustomTheme;
+
/**
* Interface for a class that can retrieve Themes from the system.
*/
@@ -36,4 +40,6 @@
void fetch(OptionsFetchedListener<ThemeBundle> callback, boolean reload);
void storeCustomTheme(CustomTheme theme);
+
+ @Nullable Builder parseCustomTheme(String serializedTheme);
}
diff --git a/src/com/android/customization/model/theme/custom/ThemeComponentOption.java b/src/com/android/customization/model/theme/custom/ThemeComponentOption.java
index 33dfc2f..352b0e7 100644
--- a/src/com/android/customization/model/theme/custom/ThemeComponentOption.java
+++ b/src/com/android/customization/model/theme/custom/ThemeComponentOption.java
@@ -145,6 +145,9 @@
@Override
public boolean isActive(CustomizationManager<ThemeComponentOption> manager) {
CustomThemeManager customThemeManager = (CustomThemeManager) manager;
+ if (getOverlayPackages().isEmpty()) {
+ return customThemeManager.getOverlayPackages().isEmpty();
+ }
for (Map.Entry<String, String> overlayEntry : getOverlayPackages().entrySet()) {
if(!Objects.equals(overlayEntry.getValue(),
customThemeManager.getOverlayPackages().get(overlayEntry.getKey()))) {
diff --git a/src/com/android/customization/picker/theme/CustomThemeActivity.java b/src/com/android/customization/picker/theme/CustomThemeActivity.java
index 9d0c7bb..6b39a78 100644
--- a/src/com/android/customization/picker/theme/CustomThemeActivity.java
+++ b/src/com/android/customization/picker/theme/CustomThemeActivity.java
@@ -15,6 +15,7 @@
*/
package com.android.customization.picker.theme;
+import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
@@ -30,7 +31,10 @@
import com.android.customization.model.CustomizationManager.Callback;
import com.android.customization.model.theme.DefaultThemeProvider;
import com.android.customization.model.theme.OverlayManagerCompat;
+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.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;
@@ -50,6 +54,9 @@
public class CustomThemeActivity extends FragmentActivity implements
CustomThemeComponentFragmentHost {
+ public static final String EXTRA_THEME_TITLE = "CustomThemeActivity.ThemeTitle";
+ public static final String EXTRA_THEME_PACKAGES = "CustomThemeActivity.ThemePackages";
+
private static final String TAG = "CustomThemeActivity";
private UserEventLogger mUserEventLogger;
@@ -64,7 +71,21 @@
super.onCreate(savedInstanceState);
CustomizationInjector injector = (CustomizationInjector) InjectorProvider.getInjector();
mUserEventLogger = injector.getUserEventLogger(this);
- mCustomThemeManager = new CustomThemeManager(null);
+ Intent intent = getIntent();
+ Builder themeBuilder = null;
+ if (intent != null && intent.hasExtra(EXTRA_THEME_PACKAGES)
+ && intent.hasExtra(EXTRA_THEME_TITLE)) {
+ ThemeBundleProvider themeProvider =
+ new DefaultThemeProvider(this, injector.getCustomizationPreferences(this));
+ themeBuilder = themeProvider.parseCustomTheme(
+ intent.getStringExtra(EXTRA_THEME_PACKAGES));
+ if (themeBuilder != null) {
+ themeBuilder.setTitle(intent.getStringExtra(EXTRA_THEME_TITLE));
+ }
+ }
+ mCustomThemeManager = new CustomThemeManager(themeBuilder == null ? null
+ : (CustomTheme) themeBuilder.build());
+
mThemeManager = new ThemeManager(
new DefaultThemeProvider(this, injector.getCustomizationPreferences(this)),
this,
diff --git a/src/com/android/customization/picker/theme/ThemeFragment.java b/src/com/android/customization/picker/theme/ThemeFragment.java
index 6df43f0..2590f21 100644
--- a/src/com/android/customization/picker/theme/ThemeFragment.java
+++ b/src/com/android/customization/picker/theme/ThemeFragment.java
@@ -28,6 +28,7 @@
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.View.OnClickListener;
import android.view.View.OnLayoutChangeListener;
import android.view.ViewGroup;
import android.widget.CheckBox;
@@ -47,10 +48,10 @@
import androidx.recyclerview.widget.RecyclerView;
import com.android.customization.model.CustomizationManager.Callback;
-import com.android.customization.model.theme.custom.CustomTheme;
import com.android.customization.model.theme.ThemeBundle;
import com.android.customization.model.theme.ThemeBundle.PreviewInfo;
import com.android.customization.model.theme.ThemeManager;
+import com.android.customization.model.theme.custom.CustomTheme;
import com.android.customization.picker.BasePreviewAdapter;
import com.android.customization.picker.BasePreviewAdapter.PreviewPage;
import com.android.customization.widget.OptionSelectorController;
@@ -82,6 +83,7 @@
}
private RecyclerView mOptionsContainer;
+ private CheckBox mUseMyWallpaperButton;
private OptionSelectorController mOptionsController;
private ThemeManager mThemeManager;
private ThemeBundle mSelectedTheme;
@@ -128,8 +130,8 @@
});
});
- ((CheckBox)view.findViewById(R.id.use_my_wallpaper)).setOnCheckedChangeListener(
- this::onUseMyWallpaperCheckChanged);
+ mUseMyWallpaperButton = view.findViewById(R.id.use_my_wallpaper);
+ mUseMyWallpaperButton.setOnCheckedChangeListener(this::onUseMyWallpaperCheckChanged);
setUpOptions(savedInstanceState);
@@ -179,20 +181,33 @@
}
private void createAdapter() {
- mAdapter = new ThemePreviewAdapter(getActivity(), mSelectedTheme);
+ mAdapter = new ThemePreviewAdapter(getActivity(), mSelectedTheme,
+ mSelectedTheme instanceof CustomTheme ? this::onEditClicked : null);
mPreviewPager.setAdapter(mAdapter);
}
+ private void onEditClicked(View view) {
+ if (mSelectedTheme instanceof CustomTheme) {
+ navigateToCustomTheme((CustomTheme) mSelectedTheme);
+ }
+ }
+
+ private void updateButtonsVisibility() {
+ mUseMyWallpaperButton.setVisibility(mSelectedTheme instanceof CustomTheme
+ ? View.GONE : View.VISIBLE);
+ }
+
private void setUpOptions(@Nullable Bundle savedInstanceState) {
mThemeManager.fetchOptions(options -> {
mOptionsController = new OptionSelectorController(mOptionsContainer, options);
mOptionsController.addListener(selected -> {
if (selected instanceof CustomTheme && !((CustomTheme) selected).isDefined()) {
- navigateToCustomTheme();
+ navigateToCustomTheme(null);
} else {
mSelectedTheme = (ThemeBundle) selected;
mSelectedTheme.setOverrideThemeWallpaper(mCurrentHomeWallpaper);
createAdapter();
+ updateButtonsVisibility();
}
});
mOptionsController.initOptions(mThemeManager);
@@ -215,10 +230,16 @@
mOptionsController.setSelectedOption(mSelectedTheme);
});
createAdapter();
+ updateButtonsVisibility();
}
- private void navigateToCustomTheme() {
+ private void navigateToCustomTheme(@Nullable CustomTheme themeToEdit) {
Intent intent = new Intent(getActivity(), CustomThemeActivity.class);
+ if (themeToEdit != null) {
+ intent.putExtra(CustomThemeActivity.EXTRA_THEME_TITLE, themeToEdit.getTitle());
+ intent.putExtra(CustomThemeActivity.EXTRA_THEME_PACKAGES,
+ themeToEdit.getSerializedPackages());
+ }
startActivity(intent);
}
@@ -227,17 +248,19 @@
@DrawableRes final int iconSrc;
@LayoutRes final int contentLayoutRes;
@ColorInt final int accentColor;
+ private final OnClickListener editClickListener;
private final LayoutInflater inflater;
private ThemePreviewPage(Context context, @StringRes int titleResId,
@DrawableRes int iconSrc, @LayoutRes int contentLayoutRes,
- @ColorInt int accentColor) {
+ @ColorInt int accentColor, OnClickListener editClickListener) {
super(null);
this.nameResId = titleResId;
this.iconSrc = iconSrc;
this.contentLayoutRes = contentLayoutRes;
this.accentColor = accentColor;
this.inflater = LayoutInflater.from(context);
+ this.editClickListener = editClickListener;
}
@Override
@@ -250,6 +273,9 @@
ViewGroup body = card.findViewById(R.id.theme_preview_card_body_container);
inflater.inflate(contentLayoutRes, body, true);
bindBody(false);
+ card.setOnClickListener(editClickListener);
+ card.findViewById(R.id.edit_label).setVisibility(editClickListener != null
+ ? View.VISIBLE : View.GONE);
}
protected boolean containsWallpaper() {
@@ -280,13 +306,14 @@
R.id.preview_color_qs_0_icon, R.id.preview_color_qs_1_icon, R.id.preview_color_qs_2_icon
};
- ThemePreviewAdapter(Activity activity, ThemeBundle theme) {
+ ThemePreviewAdapter(Activity activity, ThemeBundle theme,
+ @Nullable OnClickListener editClickListener) {
super(activity, R.layout.theme_preview_card);
final Resources res = activity.getResources();
final PreviewInfo previewInfo = theme.getPreviewInfo();
addPage(new ThemePreviewPage(activity, R.string.preview_name_font, R.drawable.ic_font,
R.layout.preview_card_font_content,
- previewInfo.resolveAccentColor(res)) {
+ previewInfo.resolveAccentColor(res), editClickListener) {
@Override
protected void bindBody(boolean forceRebind) {
TextView title = card.findViewById(R.id.font_card_title);
@@ -298,7 +325,7 @@
if (previewInfo.icons.size() >= mIconIds.length) {
addPage(new ThemePreviewPage(activity, R.string.preview_name_icon,
R.drawable.ic_wifi_24px, R.layout.preview_card_icon_content,
- previewInfo.resolveAccentColor(res)) {
+ previewInfo.resolveAccentColor(res), editClickListener) {
@Override
protected void bindBody(boolean forceRebind) {
for (int i = 0; i < mIconIds.length; i++) {
@@ -311,7 +338,7 @@
if (previewInfo.colorPreviewAsset != null) {
addPage(new ThemePreviewPage(activity, R.string.preview_name_color,
R.drawable.ic_colorize_24px, R.layout.preview_card_color_content,
- previewInfo.resolveAccentColor(res)) {
+ previewInfo.resolveAccentColor(res), editClickListener) {
@Override
protected void bindBody(boolean forceRebind) {
ColorStateList tintList = new ColorStateList(
@@ -360,7 +387,7 @@
if (previewInfo.shapePreviewAsset != null) {
addPage(new ThemePreviewPage(activity, R.string.preview_name_shape,
R.drawable.ic_shapes_24px, R.layout.preview_card_static_content,
- previewInfo.resolveAccentColor(res)) {
+ previewInfo.resolveAccentColor(res), editClickListener) {
@Override
protected void bindBody(boolean forceRebind) {
ImageView staticImage = card.findViewById(R.id.preview_static_image);
@@ -377,7 +404,7 @@
if (previewInfo.wallpaperAsset != null) {
addPage(new ThemePreviewPage(activity, R.string.preview_name_wallpaper,
R.drawable.ic_wallpaper_24px, R.layout.preview_card_wallpaper_content,
- previewInfo.resolveAccentColor(res)) {
+ previewInfo.resolveAccentColor(res), null) {
private final WallpaperPreviewLayoutListener mListener =
new WallpaperPreviewLayoutListener(theme, previewInfo);