diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 848cc08bc..4af7841e0 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -116,7 +116,7 @@
= 23) {
getWindow().setStatusBarColor(Color.TRANSPARENT);
- getWindow().getDecorView().setSystemUiVisibility(Utils.isDarkModeEnabled(this) ? 0 : View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
+ getWindow().getDecorView().setSystemUiVisibility(darkMode ? 0 : View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else {
// icons are always white back then
- getWindow().setStatusBarColor(Utils.isDarkModeEnabled(this) ? Color.TRANSPARENT : Color.argb(127, 0, 0, 0));
+ getWindow().setStatusBarColor(darkMode ? Color.TRANSPARENT : Color.argb(127, 0, 0, 0));
}
// XXX android 9 and below has a nasty rendering bug if the theme was patched earlier
- // the splash screen activity needs the fix regardless to solve a dynamic color api issue
- if (!this.getClass().getSimpleName().equals(MainActivity.class.getSimpleName())) {
- Utils.postPatchOledDarkTheme(this);
- }
+ Utils.postPatchColors(this);
}
}
diff --git a/app/src/main/java/protect/card_locker/LoyaltyCardEditActivity.java b/app/src/main/java/protect/card_locker/LoyaltyCardEditActivity.java
index 14c6aaf1c..2366eebb0 100644
--- a/app/src/main/java/protect/card_locker/LoyaltyCardEditActivity.java
+++ b/app/src/main/java/protect/card_locker/LoyaltyCardEditActivity.java
@@ -69,6 +69,7 @@ import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.widget.AppCompatTextView;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
@@ -135,6 +136,8 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
Button enterButton;
+ Toolbar toolbar;
+
int loyaltyCardId;
boolean updateLoyaltyCard;
String cardId;
@@ -291,7 +294,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.loyalty_card_edit_activity);
- Toolbar toolbar = findViewById(R.id.toolbar);
+ toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
@@ -690,9 +693,22 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
);
// Fix theming
+
int colorPrimary = MaterialColors.getColor(this, R.attr.colorPrimary, ContextCompat.getColor(this, R.color.md_theme_light_primary));
- mCropperOptions.setToolbarColor(colorPrimary);
- mCropperOptions.setStatusBarColor(colorPrimary);
+ int colorOnPrimary = MaterialColors.getColor(this, R.attr.colorOnPrimary, ContextCompat.getColor(this, R.color.md_theme_light_onPrimary));
+ int colorSurface = MaterialColors.getColor(this, R.attr.colorSurface, ContextCompat.getColor(this, R.color.md_theme_light_surface));
+ int colorOnSurface = MaterialColors.getColor(this, R.attr.colorOnSurface, ContextCompat.getColor(this, R.color.md_theme_light_onSurface));
+ int colorBackground = MaterialColors.getColor(this, android.R.attr.colorBackground, ContextCompat.getColor(this, R.color.md_theme_light_onSurface));
+ mCropperOptions.setToolbarColor(colorSurface);
+ mCropperOptions.setStatusBarColor(colorSurface);
+ mCropperOptions.setToolbarWidgetColor(colorOnSurface);
+ mCropperOptions.setRootViewBackgroundColor(colorBackground);
+ // set tool tip to be the darker of primary color
+ if (Utils.isDarkModeEnabled(this)) {
+ mCropperOptions.setActiveControlsWidgetColor(colorOnPrimary);
+ } else {
+ mCropperOptions.setActiveControlsWidgetColor(colorPrimary);
+ }
}
@Override
@@ -906,7 +922,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
protected void setColorFromIcon() {
Object icon = thumbnail.getTag();
if (icon != null && (icon instanceof Bitmap)) {
- updateTempState(LoyaltyCardField.headerColor, new Palette.Builder((Bitmap) icon).generate().getDominantColor(tempLoyaltyCard.headerColor != null ? tempLoyaltyCard.headerColor : R.attr.colorPrimary));
+ updateTempState(LoyaltyCardField.headerColor, new Palette.Builder((Bitmap) icon).generate().getDominantColor(tempLoyaltyCard.headerColor != null ? tempLoyaltyCard.headerColor : R.attr.colorPrimary));
} else {
Log.d("setColorFromIcon", "attempting header color change from icon but icon does not exist");
}
@@ -1391,13 +1407,22 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
}
}
}
- mCropperLauncher.launch(
- UCrop.of(
- sourceUri,
- destUri
- ).withOptions(mCropperOptions)
- .getIntent(this)
- );
+ Intent ucropIntent = UCrop.of(
+ sourceUri,
+ destUri
+ ).withOptions(mCropperOptions)
+ .getIntent(this);
+ ucropIntent.setClass(this, UCropWrapper.class);
+ for (int i = 0; i < toolbar.getChildCount(); i++) {
+ // send toolbar font details to ucrop wrapper
+ View child = toolbar.getChildAt(i);
+ if (child instanceof AppCompatTextView) {
+ AppCompatTextView childTextView = (AppCompatTextView) child;
+ ucropIntent.putExtra(UCropWrapper.UCROP_TOOLBAR_TYPEFACE_STYLE, childTextView.getTypeface().getStyle());
+ break;
+ }
+ }
+ mCropperLauncher.launch(ucropIntent);
}
private void generateBarcode() {
diff --git a/app/src/main/java/protect/card_locker/LoyaltyCardLockerApplication.java b/app/src/main/java/protect/card_locker/LoyaltyCardLockerApplication.java
index 3b817c540..4ed97eb92 100644
--- a/app/src/main/java/protect/card_locker/LoyaltyCardLockerApplication.java
+++ b/app/src/main/java/protect/card_locker/LoyaltyCardLockerApplication.java
@@ -16,6 +16,5 @@ public class LoyaltyCardLockerApplication extends Application {
Settings settings = new Settings(this);
AppCompatDelegate.setDefaultNightMode(settings.getTheme());
- DynamicColors.applyToActivitiesIfAvailable(this);
}
}
diff --git a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java
index e2654a158..24ab41787 100644
--- a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java
+++ b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java
@@ -33,6 +33,7 @@ import android.widget.Toast;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
+import com.google.android.material.color.MaterialColors;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.io.UnsupportedEncodingException;
@@ -580,10 +581,13 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
editButton.setBackgroundTintList(ColorStateList.valueOf(complementaryColor));
Drawable editButtonIcon = editButton.getDrawable();
editButtonIcon.mutate();
+ int colorPrimary = MaterialColors.getColor(this, R.attr.colorPrimary, ContextCompat.getColor(this, R.color.md_theme_light_primary));
+ int colorOnPrimary = MaterialColors.getColor(this, R.attr.colorOnPrimary, ContextCompat.getColor(this, R.color.md_theme_light_onPrimary));
+ boolean darkMode = Utils.isDarkModeEnabled(this);
if (Utils.needsDarkForeground(complementaryColor)) {
- editButtonIcon.setTint(ContextCompat.getColor(this, R.color.md_theme_light_onBackground));
+ editButtonIcon.setTint(darkMode ? colorOnPrimary : colorPrimary);
} else {
- editButtonIcon.setTint(ContextCompat.getColor(this, R.color.md_theme_dark_onBackground));
+ editButtonIcon.setTint(darkMode ? colorPrimary : colorOnPrimary);
}
editButton.setImageDrawable(editButtonIcon);
@@ -647,7 +651,6 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
dotIndicator.removeAllViews();
if (imageTypes.size() >= 2) {
dots = new ImageView[imageTypes.size()];
- boolean darkMode = Utils.isDarkModeEnabled(getApplicationContext());
for (int i = 0; i < imageTypes.size(); i++) {
dots[i] = new ImageView(this);
diff --git a/app/src/main/java/protect/card_locker/MainActivity.java b/app/src/main/java/protect/card_locker/MainActivity.java
index 0f4906d0b..81c5d6536 100644
--- a/app/src/main/java/protect/card_locker/MainActivity.java
+++ b/app/src/main/java/protect/card_locker/MainActivity.java
@@ -180,20 +180,10 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
protected void onCreate(Bundle inputSavedInstanceState) {
super.onCreate(inputSavedInstanceState);
SplashScreen.installSplashScreen(this);
-
- // onPreCreate can't tell this activity uses a material theme due to splash screen, force color application here
- DynamicColors.applyIfAvailable(this);
- Utils.patchOledDarkTheme(this);
setTitle(R.string.app_name);
-
+ // XXX color patching has to be done again after setting splash screen
+ Utils.patchColors(this);
setContentView(R.layout.main_activity);
-
- // XXX more dynamic color fixing due to splash screen
- // without this the background color will get stuck with the old color before dynamic color
- TypedValue typedValue = new TypedValue();
- getTheme().resolveAttribute(android.R.attr.colorBackground, typedValue, true);
- findViewById(android.R.id.content).setBackgroundColor(typedValue.data);
-
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
diff --git a/app/src/main/java/protect/card_locker/UCropWrapper.java b/app/src/main/java/protect/card_locker/UCropWrapper.java
new file mode 100644
index 000000000..2f32d5001
--- /dev/null
+++ b/app/src/main/java/protect/card_locker/UCropWrapper.java
@@ -0,0 +1,79 @@
+package protect.card_locker;
+
+import android.content.Intent;
+import android.graphics.Color;
+import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+
+import androidx.annotation.Nullable;
+import androidx.appcompat.widget.AppCompatImageView;
+import androidx.core.content.ContextCompat;
+import androidx.core.graphics.ColorUtils;
+
+import com.google.android.material.color.MaterialColors;
+import com.google.android.material.textview.MaterialTextView;
+import com.yalantis.ucrop.UCropActivity;
+
+public class UCropWrapper extends UCropActivity {
+ public static final String UCROP_TOOLBAR_TYPEFACE_STYLE = "ucop_toolbar_typeface_style";
+
+ @Override
+ protected void onPostCreate(@Nullable Bundle savedInstanceState) {
+ super.onPostCreate(savedInstanceState);
+ boolean darkMode = Utils.isDarkModeEnabled(this);
+ // setup status bar to look like the rest of the app
+ if (Build.VERSION.SDK_INT >= 23) {
+ getWindow().getDecorView().setSystemUiVisibility(darkMode ? 0 : View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
+ } else {
+ // icons are always white back then
+ if (!darkMode) {
+ getWindow().setStatusBarColor(ColorUtils.compositeColors(Color.argb(127, 0, 0, 0), getWindow().getStatusBarColor()));
+ }
+ }
+
+ // find and check views that we wish to color modify
+ // for when we update ucrop or switch to another cropper
+ View check = findViewById(com.yalantis.ucrop.R.id.wrapper_controls);
+ if (check instanceof FrameLayout) {
+ FrameLayout controls = (FrameLayout) check;
+ check = findViewById(com.yalantis.ucrop.R.id.wrapper_states);
+ if (check instanceof LinearLayout) {
+ LinearLayout states = (LinearLayout) check;
+ for (int i = 0; i < controls.getChildCount(); i++) {
+ check = controls.getChildAt(i);
+ if (check instanceof AppCompatImageView) {
+ AppCompatImageView controlsBackgroundImage = (AppCompatImageView) check;
+ // everything gathered and are as expected, now perform color patching
+ Utils.patchColors(this);
+ int colorSurface = MaterialColors.getColor(this, R.attr.colorSurface, ContextCompat.getColor(this, R.color.md_theme_light_surface));
+ int colorOnSurface = MaterialColors.getColor(this, R.attr.colorOnSurface, ContextCompat.getColor(this, R.color.md_theme_light_onSurface));
+
+ Drawable controlsBackgroundImageDrawable = controlsBackgroundImage.getBackground();
+ controlsBackgroundImageDrawable.mutate();
+ controlsBackgroundImageDrawable.setTint(darkMode ? colorOnSurface : colorSurface);
+ controlsBackgroundImage.setBackgroundDrawable(controlsBackgroundImageDrawable);
+
+ states.setBackgroundColor(darkMode ? colorSurface : colorOnSurface);
+ break;
+ }
+ }
+ }
+ }
+
+ // change toolbar font
+ check = findViewById(com.yalantis.ucrop.R.id.toolbar_title);
+ if (check instanceof MaterialTextView) {
+ MaterialTextView toolbarTextview = (MaterialTextView) check;
+ Intent intent = getIntent();
+ int style = intent.getIntExtra(UCROP_TOOLBAR_TYPEFACE_STYLE, -1);
+ if (style != -1) {
+ toolbarTextview.setTypeface(Typeface.defaultFromStyle(style));
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/protect/card_locker/Utils.java b/app/src/main/java/protect/card_locker/Utils.java
index f5e4fd328..23f7cb84e 100644
--- a/app/src/main/java/protect/card_locker/Utils.java
+++ b/app/src/main/java/protect/card_locker/Utils.java
@@ -17,6 +17,7 @@ import android.util.Log;
import android.util.TypedValue;
import android.widget.Toast;
+import com.google.android.material.color.DynamicColors;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
@@ -464,21 +465,45 @@ public class Utils {
}
// replace colors in the current theme
- // use before views are inflated, after dynamic color
- public static void patchOledDarkTheme(AppCompatActivity activity) {
- if (isDarkModeEnabled(activity) && new Settings(activity).getOledDark()) {
- activity.getTheme().applyStyle(R.style.DarkBackground, true);
+ public static void patchColors(AppCompatActivity activity) {
+ Settings settings = new Settings(activity);
+ String color = settings.getColor();
+
+ Resources.Theme theme = activity.getTheme();
+ Resources resources = activity.getResources();
+ if (color.equals(resources.getString(R.string.settings_key_pink_theme))) {
+ theme.applyStyle(R.style.pink, true);
+ } else if (color.equals(resources.getString(R.string.settings_key_magenta_theme))) {
+ theme.applyStyle(R.style.magenta, true);
+ } else if (color.equals(resources.getString(R.string.settings_key_violet_theme))) {
+ theme.applyStyle(R.style.violet, true);
+ } else if (color.equals(resources.getString(R.string.settings_key_blue_theme))) {
+ theme.applyStyle(R.style.blue, true);
+ } else if (color.equals(resources.getString(R.string.settings_key_sky_blue_theme))) {
+ theme.applyStyle(R.style.skyblue, true);
+ } else if (color.equals(resources.getString(R.string.settings_key_green_theme))) {
+ theme.applyStyle(R.style.green, true);
+ } else if (color.equals(resources.getString(R.string.settings_key_brown_theme))) {
+ theme.applyStyle(R.style.brown, true);
+ } else if (color.equals(resources.getString(R.string.settings_key_catima_theme))) {
+ // catima theme is AppTheme itself, no dynamic colors nor applyStyle
+ } else {
+ // final catch all in case of invalid theme value from older versions
+ // also handles R.string.settings_key_system_theme
+ DynamicColors.applyIfAvailable(activity);
+ }
+
+ if (isDarkModeEnabled(activity) && settings.getOledDark()) {
+ theme.applyStyle(R.style.DarkBackground, true);
}
}
// XXX android 9 and below has issues with patched theme where the background becomes a
// rendering mess
// use after views are inflated
- public static void postPatchOledDarkTheme(AppCompatActivity activity) {
- if (isDarkModeEnabled(activity) && new Settings(activity).getOledDark()) {
- TypedValue typedValue = new TypedValue();
- activity.getTheme().resolveAttribute(android.R.attr.colorBackground, typedValue, true);
- activity.findViewById(android.R.id.content).setBackgroundColor(typedValue.data);
- }
+ public static void postPatchColors(AppCompatActivity activity) {
+ TypedValue typedValue = new TypedValue();
+ activity.getTheme().resolveAttribute(android.R.attr.colorBackground, typedValue, true);
+ activity.findViewById(android.R.id.content).setBackgroundColor(typedValue.data);
}
}
diff --git a/app/src/main/java/protect/card_locker/preferences/Settings.java b/app/src/main/java/protect/card_locker/preferences/Settings.java
index bd77dc135..345107429 100644
--- a/app/src/main/java/protect/card_locker/preferences/Settings.java
+++ b/app/src/main/java/protect/card_locker/preferences/Settings.java
@@ -107,4 +107,8 @@ public class Settings {
public boolean getOledDark() {
return getBoolean(R.string.settings_key_oled_dark, false);
}
+
+ public String getColor() {
+ return getString(R.string.setting_key_theme_color, mContext.getResources().getString(R.string.settings_key_system_theme));
+ }
}
diff --git a/app/src/main/java/protect/card_locker/preferences/SettingsActivity.java b/app/src/main/java/protect/card_locker/preferences/SettingsActivity.java
index bb710b1f7..d2fc17448 100644
--- a/app/src/main/java/protect/card_locker/preferences/SettingsActivity.java
+++ b/app/src/main/java/protect/card_locker/preferences/SettingsActivity.java
@@ -19,6 +19,8 @@ import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
+import com.google.android.material.color.DynamicColors;
+
import nl.invissvenska.numberpickerpreference.NumberDialogPreference;
import nl.invissvenska.numberpickerpreference.NumberPickerPreferenceDialogFragment;
import protect.card_locker.CatimaAppCompatActivity;
@@ -140,6 +142,17 @@ public class SettingsActivity extends CatimaAppCompatActivity {
refreshActivity(true);
return true;
});
+
+ ListPreference colorPreference = findPreference(getResources().getString(R.string.setting_key_theme_color));
+ assert colorPreference != null;
+ colorPreference.setOnPreferenceChangeListener((preference, o) -> {
+ refreshActivity(true);
+ return true;
+ });
+ if (!DynamicColors.isDynamicColorAvailable()) {
+ colorPreference.setEntryValues(R.array.color_values_no_dynamic);
+ colorPreference.setEntries(R.array.color_value_strings_no_dynamic);
+ }
}
private void refreshActivity(boolean reloadMain) {
diff --git a/app/src/main/res/layout/settings_activity.xml b/app/src/main/res/layout/settings_activity.xml
index 8630f2c4a..e7351758a 100644
--- a/app/src/main/res/layout/settings_activity.xml
+++ b/app/src/main/res/layout/settings_activity.xml
@@ -1,9 +1,11 @@
-
+ android:fitsSystemWindows="true"
+ tools:context="protect.card_locker.preferences.SettingsActivity">
+ android:layout_height="?attr/actionBarSize" />
+ android:layout_height="match_parent"
+ android:layout_marginTop="?attr/actionBarSize" />
-
+
\ No newline at end of file
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
index 939599068..a36d1b0b9 100644
--- a/app/src/main/res/values-night/themes.xml
+++ b/app/src/main/res/values-night/themes.xml
@@ -38,4 +38,208 @@
- #000000
- #000000
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/settings.xml b/app/src/main/res/values/settings.xml
index 4c472fc4c..96db0eecb 100644
--- a/app/src/main/res/values/settings.xml
+++ b/app/src/main/res/values/settings.xml
@@ -12,6 +12,52 @@
- @string/settings_dark_theme
+
+ - @string/settings_key_system_theme
+ - @string/settings_key_catima_theme
+ - @string/settings_key_pink_theme
+ - @string/settings_key_magenta_theme
+ - @string/settings_key_violet_theme
+ - @string/settings_key_blue_theme
+ - @string/settings_key_sky_blue_theme
+ - @string/settings_key_green_theme
+ - @string/settings_key_brown_theme
+
+
+
+ - @string/settings_system_theme
+ - @string/settings_catima_theme
+ - @string/settings_pink_theme
+ - @string/settings_magenta_theme
+ - @string/settings_violet_theme
+ - @string/settings_blue_theme
+ - @string/settings_sky_blue_theme
+ - @string/settings_green_theme
+ - @string/settings_brown_theme
+
+
+
+ - @string/settings_key_system_theme
+ - @string/settings_key_pink_theme
+ - @string/settings_key_magenta_theme
+ - @string/settings_key_violet_theme
+ - @string/settings_key_blue_theme
+ - @string/settings_key_sky_blue_theme
+ - @string/settings_key_green_theme
+ - @string/settings_key_brown_theme
+
+
+
+ - @string/settings_catima_theme
+ - @string/settings_pink_theme
+ - @string/settings_magenta_theme
+ - @string/settings_violet_theme
+ - @string/settings_blue_theme
+ - @string/settings_sky_blue_theme
+ - @string/settings_green_theme
+ - @string/settings_brown_theme
+
+
- bg
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 9b0486158..6932df1b3 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -52,4 +52,208 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index 14e295d34..16624a099 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -15,6 +15,15 @@
app:iconSpaceReserved="false"
app:singleLineTitle="false" />
+
+