diff --git a/res/color/option_border_color.xml b/res/color/option_border_color.xml
new file mode 100644
index 0000000..880724c
--- /dev/null
+++ b/res/color/option_border_color.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
diff --git a/res/drawable/icon_background.xml b/res/drawable/icon_background.xml
new file mode 100644
index 0000000..e13ce6d
--- /dev/null
+++ b/res/drawable/icon_background.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
diff --git a/res/drawable/option_border_custom.xml b/res/drawable/option_border_custom.xml
new file mode 100644
index 0000000..61f176e
--- /dev/null
+++ b/res/drawable/option_border_custom.xml
@@ -0,0 +1,21 @@
+
+
+ -
+
+
+
+
+
+
+
diff --git a/res/drawable/option_border_edge_custom.xml b/res/drawable/option_border_edge_custom.xml
new file mode 100644
index 0000000..197b445
--- /dev/null
+++ b/res/drawable/option_border_edge_custom.xml
@@ -0,0 +1,31 @@
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
diff --git a/res/layout/fonts_option.xml b/res/layout/fonts_option.xml
new file mode 100644
index 0000000..7e84826
--- /dev/null
+++ b/res/layout/fonts_option.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/layout/icon_option.xml b/res/layout/icon_option.xml
new file mode 100644
index 0000000..99324db
--- /dev/null
+++ b/res/layout/icon_option.xml
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/layout/item_option.xml b/res/layout/item_option.xml
new file mode 100644
index 0000000..113324a
--- /dev/null
+++ b/res/layout/item_option.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/layout/item_view.xml b/res/layout/item_view.xml
new file mode 100644
index 0000000..743d088
--- /dev/null
+++ b/res/layout/item_view.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
diff --git a/res/values/cherish_strings.xml b/res/values/cherish_strings.xml
index f84b7f3..f55120d 100644
--- a/res/values/cherish_strings.xml
+++ b/res/values/cherish_strings.xml
@@ -131,11 +131,13 @@
Icon shape
- Accent color
+ Set system icon shape style
Headline / Body font
-
- Statusbar icon
+ Set system font style
+
+ Icon pack
+ Set custom icon pack style
Signal
diff --git a/res/values/cherish_styles.xml b/res/values/cherish_styles.xml
index e2586a4..be0f7b7 100644
--- a/res/values/cherish_styles.xml
+++ b/res/values/cherish_styles.xml
@@ -22,4 +22,5 @@
100dp
20dp
+ #5f6368
diff --git a/res/values/colors.xml b/res/values/colors.xml
new file mode 100644
index 0000000..5cf51ff
--- /dev/null
+++ b/res/values/colors.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+ #5f6368
+ @color/google_grey700
+ @color/edit_background_base
+
+
diff --git a/res/values/styles.xml b/res/values/styles.xml
new file mode 100644
index 0000000..59a404e
--- /dev/null
+++ b/res/values/styles.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
diff --git a/res/xml/cherish_settings_theme.xml b/res/xml/cherish_settings_theme.xml
index 74060dd..44658e4 100644
--- a/res/xml/cherish_settings_theme.xml
+++ b/res/xml/cherish_settings_theme.xml
@@ -28,17 +28,26 @@
android:fragment="com.android.settings.display.darkmode.DarkModeSettingsFragment"
settings:controller="com.android.settings.display.DarkUIPreferenceController" />
-
+
+ android:title="@string/theme_customization_font_title"
+ android:summary="@string/theme_customization_font_summary"
+ android:fragment="com.cherish.settings.fragments.ui.FontsPicker"/>
-
-
-
+
+ android:title="@string/theme_customization_icon_pack_title"
+ android:summary="@string/theme_customization_icon_pack_summary"
+ android:fragment="com.cherish.settings.fragments.ui.StatusbarIcons"/>
+
+
+
controllers = new ArrayList<>();
- controllers.add(new OverlayCategoryPreferenceController(context,
- "android.theme.customization.font"));
- controllers.add(new OverlayCategoryPreferenceController(context,
- "android.theme.customization.adaptive_icon_shape"));
- controllers.add(new OverlayCategoryPreferenceController(context,
- "android.theme.customization.icon_pack"));
controllers.add(new OverlayCategoryPreferenceController(context,
"android.theme.customization.signal_icon"));
controllers.add(new OverlayCategoryPreferenceController(context,
diff --git a/src/com/cherish/settings/fragments/ui/FontsPicker.java b/src/com/cherish/settings/fragments/ui/FontsPicker.java
new file mode 100644
index 0000000..98aef42
--- /dev/null
+++ b/src/com/cherish/settings/fragments/ui/FontsPicker.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2020-22 The CherishOS 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.cherish.settings.fragments.ui;
+
+import static android.os.UserHandle.USER_SYSTEM;
+import static com.android.internal.util.cherish.ThemeUtils.FONT_KEY;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.Typeface;
+import android.graphics.drawable.AnimationDrawable;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.SearchIndexableResource;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup.LayoutParams;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.content.res.ResourcesCompat;
+import androidx.preference.Preference.OnPreferenceChangeListener;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.PreferenceViewHolder;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.RecyclerView.ViewHolder;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.util.cherish.ThemeUtils;
+
+import com.android.settings.R;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settingslib.search.Indexable;
+
+import com.bumptech.glide.Glide;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+public class FontsPicker extends SettingsPreferenceFragment {
+
+ private RecyclerView mRecyclerView;
+ private ThemeUtils mThemeUtils;
+ private String mCategory = FONT_KEY;
+
+ private List mPkgs;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getActivity().setTitle(R.string.theme_customization_font_title);
+
+ mThemeUtils = new ThemeUtils(getActivity());
+ mPkgs = mThemeUtils.getOverlayPackagesForCategory(mCategory, "android");
+ Collections.sort(mPkgs);
+ }
+
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
+ View view = inflater.inflate(
+ R.layout.item_view, container, false);
+
+ mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
+ GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 1);
+ mRecyclerView.setLayoutManager(gridLayoutManager);
+ Adapter mAdapter = new Adapter(getActivity());
+ mRecyclerView.setAdapter(mAdapter);
+
+ return view;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.CHERISH_SETTINGS;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ }
+
+ public class Adapter extends RecyclerView.Adapter {
+ Context context;
+ String mSelectedPkg;
+ String mAppliedPkg;
+
+ public Adapter(Context context) {
+ this.context = context;
+ }
+
+ @Override
+ public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.fonts_option, parent, false);
+ CustomViewHolder vh = new CustomViewHolder(v);
+ return vh;
+ }
+
+ @Override
+ public void onBindViewHolder(CustomViewHolder holder, final int position) {
+ String pkg = mPkgs.get(position);
+ String label = getLabel(holder.itemView.getContext(), pkg);
+
+ String currentPackageName = mThemeUtils.getOverlayInfos(mCategory).stream()
+ .filter(info -> info.isEnabled())
+ .map(info -> info.packageName)
+ .findFirst()
+ .orElse("android");
+
+ holder.title.setText("android".equals(pkg) ? "Default" : label);
+ holder.title.setTextSize(20);
+ holder.title.setTypeface(getTypeface(holder.title.getContext(), pkg));
+ holder.name.setVisibility(View.GONE);
+
+ if (currentPackageName.equals(pkg)) {
+ mAppliedPkg = pkg;
+ if (mSelectedPkg == null) {
+ mSelectedPkg = pkg;
+ }
+ }
+
+ holder.itemView.setActivated(pkg == mSelectedPkg);
+ holder.itemView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ updateActivatedStatus(mSelectedPkg, false);
+ updateActivatedStatus(pkg, true);
+ mSelectedPkg = pkg;
+ enableOverlays(position);
+ }
+ });
+ }
+
+ @Override
+ public int getItemCount() {
+ return mPkgs.size();
+ }
+
+ public class CustomViewHolder extends RecyclerView.ViewHolder {
+ TextView name;
+ TextView title;
+ public CustomViewHolder(View itemView) {
+ super(itemView);
+ title = (TextView) itemView.findViewById(R.id.option_title);
+ name = (TextView) itemView.findViewById(R.id.option_label);
+ }
+ }
+
+ private void updateActivatedStatus(String pkg, boolean isActivated) {
+ int index = mPkgs.indexOf(pkg);
+ if (index < 0) {
+ return;
+ }
+ RecyclerView.ViewHolder holder = mRecyclerView.findViewHolderForAdapterPosition(index);
+ if (holder != null && holder.itemView != null) {
+ holder.itemView.setActivated(isActivated);
+ }
+ }
+ }
+
+ public Typeface getTypeface(Context context, String pkg) {
+ try {
+ PackageManager pm = context.getPackageManager();
+ Resources res = pkg.equals("android") ? Resources.getSystem()
+ : pm.getResourcesForApplication(pkg);
+ return Typeface.create(res.getString(
+ res.getIdentifier("config_bodyFontFamily",
+ "string", pkg)), Typeface.NORMAL);
+ }
+ catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public String getLabel(Context context, String pkg) {
+ PackageManager pm = context.getPackageManager();
+ try {
+ return pm.getApplicationInfo(pkg, 0)
+ .loadLabel(pm).toString();
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ return pkg;
+ }
+
+ public void enableOverlays(int position) {
+ mThemeUtils.setOverlayEnabled(mCategory, mPkgs.get(position));
+ }
+}
diff --git a/src/com/cherish/settings/fragments/ui/IconShapes.java b/src/com/cherish/settings/fragments/ui/IconShapes.java
new file mode 100644
index 0000000..089dced
--- /dev/null
+++ b/src/com/cherish/settings/fragments/ui/IconShapes.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2020-22 The CherishOS Projects
+ *
+ * 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.cherish.settings.fragments.ui;
+
+import static com.android.internal.util.cherish.ThemeUtils.ICON_SHAPE_KEY;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.graphics.drawable.AnimationDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.ShapeDrawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.SearchIndexableResource;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup.LayoutParams;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.content.res.ResourcesCompat;
+import androidx.core.graphics.ColorUtils;
+import androidx.preference.Preference.OnPreferenceChangeListener;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.PreferenceViewHolder;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.RecyclerView.ViewHolder;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.util.cherish.ThemeUtils;
+
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.Utils;
+import com.android.settingslib.search.Indexable;
+
+import com.bumptech.glide.Glide;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Arrays;
+
+import org.json.JSONObject;
+import org.json.JSONException;
+
+public class IconShapes extends SettingsPreferenceFragment {
+
+ private RecyclerView mRecyclerView;
+ private ThemeUtils mThemeUtils;
+ private String mCategory = ICON_SHAPE_KEY;
+
+ private List mPkgs;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getActivity().setTitle(R.string.theme_customization_icon_shape_title);
+
+ mThemeUtils = new ThemeUtils(getActivity());
+ mPkgs = mThemeUtils.getOverlayPackagesForCategory(mCategory, "android");
+ Collections.sort(mPkgs);
+ }
+
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
+ View view = inflater.inflate(
+ R.layout.item_view, container, false);
+
+ mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
+ GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 3);
+ mRecyclerView.setLayoutManager(gridLayoutManager);
+ Adapter mAdapter = new Adapter(getActivity());
+ mRecyclerView.setAdapter(mAdapter);
+
+ return view;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.CHERISH_SETTINGS;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ }
+
+ public class Adapter extends RecyclerView.Adapter {
+ Context context;
+ String mSelectedPkg;
+ String mAppliedPkg;
+
+ public Adapter(Context context) {
+ this.context = context;
+ }
+
+ @Override
+ public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_option, parent, false);
+ CustomViewHolder vh = new CustomViewHolder(v);
+ return vh;
+ }
+
+ @Override
+ public void onBindViewHolder(CustomViewHolder holder, final int position) {
+ String pkg = mPkgs.get(position);
+
+ holder.image.setBackgroundDrawable(mThemeUtils.createShapeDrawable(pkg));
+
+ String currentPackageName = mThemeUtils.getOverlayInfos(mCategory).stream()
+ .filter(info -> info.isEnabled())
+ .map(info -> info.packageName)
+ .findFirst()
+ .orElse("android");
+
+ holder.name.setText("android".equals(pkg) ? "Default" : getLabel(holder.name.getContext(), pkg));
+
+ final boolean isDefault = "android".equals(currentPackageName) && "android".equals(pkg);
+ final int color = ColorUtils.setAlphaComponent(
+ Utils.getColorAttrDefaultColor(getContext(), android.R.attr.colorAccent),
+ pkg.equals(currentPackageName) || isDefault ? 170 : 75);
+ holder.image.setBackgroundTintList(ColorStateList.valueOf(color));
+
+ holder.itemView.findViewById(R.id.option_tile).setBackgroundDrawable(null);
+ holder.itemView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ enableOverlays(position);
+ }
+ });
+ }
+
+ @Override
+ public int getItemCount() {
+ return mPkgs.size();
+ }
+
+ public class CustomViewHolder extends RecyclerView.ViewHolder {
+ TextView name;
+ ImageView image;
+ public CustomViewHolder(View itemView) {
+ super(itemView);
+ name = (TextView) itemView.findViewById(R.id.option_label);
+ image = (ImageView) itemView.findViewById(R.id.option_thumbnail);
+ }
+ }
+ }
+
+ public Drawable getDrawable(Context context, String pkg, String drawableName) {
+ try {
+ PackageManager pm = context.getPackageManager();
+ Resources res = pkg.equals("android") ? Resources.getSystem()
+ : pm.getResourcesForApplication(pkg);
+ return res.getDrawable(res.getIdentifier(drawableName, "drawable", pkg));
+ }
+ catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public String getLabel(Context context, String pkg) {
+ PackageManager pm = context.getPackageManager();
+ try {
+ return pm.getApplicationInfo(pkg, 0)
+ .loadLabel(pm).toString();
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ return pkg;
+ }
+
+ public void enableOverlays(int position) {
+ mThemeUtils.setOverlayEnabled(mCategory, mPkgs.get(position));
+ }
+}
diff --git a/src/com/cherish/settings/fragments/ui/StatusbarIcons.java b/src/com/cherish/settings/fragments/ui/StatusbarIcons.java
new file mode 100644
index 0000000..0b4c814
--- /dev/null
+++ b/src/com/cherish/settings/fragments/ui/StatusbarIcons.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2020-22 The CherishOS 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.cherish.settings.fragments.ui;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.AnimationDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.provider.SearchIndexableResource;
+import android.provider.Settings;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.Gravity;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.FrameLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+import android.text.TextUtils;
+import androidx.preference.PreferenceViewHolder;
+import android.view.ViewGroup.LayoutParams;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.RecyclerView.ViewHolder;
+import androidx.recyclerview.widget.RecyclerView;
+import android.net.Uri;
+import androidx.core.content.res.ResourcesCompat;
+import androidx.preference.Preference;
+import androidx.preference.Preference.OnPreferenceChangeListener;
+import androidx.preference.PreferenceScreen;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.R;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.search.Indexable;
+import com.android.settings.SettingsPreferenceFragment;
+
+import com.bumptech.glide.Glide;
+
+import com.android.internal.util.cherish.ThemeUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Arrays;
+
+import org.json.JSONObject;
+import org.json.JSONException;
+
+public class StatusbarIcons extends SettingsPreferenceFragment {
+
+ private RecyclerView mRecyclerView;
+ private ThemeUtils mThemeUtils;
+ private String mCategory = "android.theme.customization.icon_pack.android";
+
+ private List mPkgs;
+
+ Map overlayMap = new HashMap();
+ {
+ overlayMap.put("com.android.settings", "android.theme.customization.icon_pack.settings");
+ overlayMap.put("com.android.systemui", "android.theme.customization.icon_pack.systemui");
+ overlayMap.put("com.google.android.apps.nexuslauncher", "android.theme.customization.icon_pack.launcher");
+ overlayMap.put("com.google.android.apps.wallpaper", "android.theme.customization.icon_pack.themepicker");
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getActivity().setTitle(R.string.theme_customization_icon_pack_title);
+
+ mThemeUtils = new ThemeUtils(getActivity());
+ mPkgs = mThemeUtils.getOverlayPackagesForCategory(mCategory, "android");
+ Collections.sort(mPkgs);
+ }
+
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
+ View view = inflater.inflate(
+ R.layout.item_view, container, false);
+
+ mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
+ GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 3);
+ mRecyclerView.setLayoutManager(gridLayoutManager);
+ Adapter mAdapter = new Adapter(getActivity());
+ mRecyclerView.setAdapter(mAdapter);
+
+ return view;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.CHERISH_SETTINGS;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ }
+
+ public class Adapter extends RecyclerView.Adapter {
+ Context context;
+ String mSelectedPkg;
+ String mAppliedPkg;
+
+ public Adapter(Context context) {
+ this.context = context;
+ }
+
+ @Override
+ public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.icon_option, parent, false);
+ CustomViewHolder vh = new CustomViewHolder(v);
+ return vh;
+ }
+
+ @Override
+ public void onBindViewHolder(CustomViewHolder holder, final int position) {
+ String iconPkg = mPkgs.get(position);
+
+ holder.image1.setBackgroundDrawable(getDrawable(holder.image1.getContext(), iconPkg, "ic_wifi_signal_4"));
+ holder.image2.setBackgroundDrawable(getDrawable(holder.image2.getContext(), iconPkg, "ic_signal_cellular_4_4_bar"));
+ holder.image3.setBackgroundDrawable(getDrawable(holder.image3.getContext(), iconPkg, "ic_qs_airplane"));
+ holder.image4.setBackgroundDrawable(getDrawable(holder.image4.getContext(), iconPkg, "ic_qs_flashlight"));
+
+ String currentPackageName = mThemeUtils.getOverlayInfos(mCategory).stream()
+ .filter(info -> info.isEnabled())
+ .map(info -> info.packageName)
+ .findFirst()
+ .orElse("android");
+
+ holder.name.setText("android".equals(iconPkg) ? "Default" : getLabel(holder.name.getContext(), iconPkg));
+
+ if (currentPackageName.equals(iconPkg)) {
+ mAppliedPkg = iconPkg;
+ if (mSelectedPkg == null) {
+ mSelectedPkg = iconPkg;
+ }
+ }
+
+ holder.itemView.setActivated(iconPkg == mSelectedPkg);
+ holder.itemView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ updateActivatedStatus(mSelectedPkg, false);
+ updateActivatedStatus(iconPkg, true);
+ mSelectedPkg = iconPkg;
+ enableOverlays(position);
+ }
+ });
+ }
+
+ @Override
+ public int getItemCount() {
+ return mPkgs.size();
+ }
+
+ public class CustomViewHolder extends RecyclerView.ViewHolder {
+ TextView name;
+ ImageView image1;
+ ImageView image2;
+ ImageView image3;
+ ImageView image4;
+ public CustomViewHolder(View itemView) {
+ super(itemView);
+ name = (TextView) itemView.findViewById(R.id.option_label);
+ image1 = (ImageView) itemView.findViewById(R.id.image1);
+ image2 = (ImageView) itemView.findViewById(R.id.image2);
+ image3 = (ImageView) itemView.findViewById(R.id.image3);
+ image4 = (ImageView) itemView.findViewById(R.id.image4);
+ }
+ }
+
+ private void updateActivatedStatus(String pkg, boolean isActivated) {
+ int index = mPkgs.indexOf(pkg);
+ if (index < 0) {
+ return;
+ }
+ RecyclerView.ViewHolder holder = mRecyclerView.findViewHolderForAdapterPosition(index);
+ if (holder != null && holder.itemView != null) {
+ holder.itemView.setActivated(isActivated);
+ }
+ }
+ }
+
+ public Drawable getDrawable(Context context, String pkg, String drawableName) {
+ try {
+ PackageManager pm = context.getPackageManager();
+ Resources res = pkg.equals("android") ? Resources.getSystem()
+ : pm.getResourcesForApplication(pkg);
+ int resId = res.getIdentifier(drawableName, "drawable", pkg);
+ if (resId == 0) {
+ return Resources.getSystem().getDrawable(
+ Resources.getSystem().getIdentifier(drawableName, "drawable", "android"));
+ }
+ return res.getDrawable(resId);
+ }
+ catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public String getLabel(Context context, String pkg) {
+ PackageManager pm = context.getPackageManager();
+ try {
+ return pm.getApplicationInfo(pkg, 0)
+ .loadLabel(pm).toString();
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ return pkg;
+ }
+
+ public void enableOverlays(int position) {
+ mThemeUtils.setOverlayEnabled(mCategory, mPkgs.get(position));
+ String pattern = "android".equals(mPkgs.get(position)) ? ""
+ : mPkgs.get(position).split("\\.")[4];
+ for (Map.Entry entry : overlayMap.entrySet()) {
+ enableOverlay(entry.getValue(), entry.getKey(), pattern);
+ }
+ }
+
+ public void enableOverlay(String category, String target, String pattern) {
+ if (pattern.isEmpty()) {
+ mThemeUtils.setOverlayEnabled(category, "android");
+ return;
+ }
+ for (String pkg: mThemeUtils.getOverlayPackagesForCategory(category, target)) {
+ if (pkg.contains(pattern)) {
+ mThemeUtils.setOverlayEnabled(category, pkg);
+ }
+ }
+ }
+}
\ No newline at end of file