From 808d31fce4fe61df0fe1c50c9b5944967980f30a Mon Sep 17 00:00:00 2001 From: Markus Litz Date: Sun, 19 Apr 2026 15:55:07 +0200 Subject: [PATCH 1/3] A simple implementation to use the system default to switche between dark/light theme. --- .../gaulupeau/apps/Poche/data/Settings.java | 8 ++++++ .../fr/gaulupeau/apps/Poche/ui/Themes.java | 27 +++++++++++++++---- .../res/values/strings-preference-keys.xml | 1 + app/src/main/res/values/strings.xml | 2 ++ app/src/main/res/xml/preferences.xml | 5 ++++ 5 files changed, 38 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/fr/gaulupeau/apps/Poche/data/Settings.java b/app/src/main/java/fr/gaulupeau/apps/Poche/data/Settings.java index 4e11794b8..29b1f0822 100644 --- a/app/src/main/java/fr/gaulupeau/apps/Poche/data/Settings.java +++ b/app/src/main/java/fr/gaulupeau/apps/Poche/data/Settings.java @@ -448,6 +448,14 @@ public void setTheme(Themes.Theme theme) { setString(R.string.pref_key_ui_theme, theme.toString()); } + public boolean isAutoThemeEnabled() { + return getBoolean(R.string.pref_key_ui_theme_auto, false); + } + + public void setAutoThemeEnabled(boolean value) { + setBoolean(R.string.pref_key_ui_theme_auto, value); + } + public boolean isVolumeButtonsScrollingEnabled() { return getBoolean(R.string.pref_key_ui_volumeButtonsScrolling_enabled, false); } diff --git a/app/src/main/java/fr/gaulupeau/apps/Poche/ui/Themes.java b/app/src/main/java/fr/gaulupeau/apps/Poche/ui/Themes.java index 1bc3ec14b..ee806afc3 100644 --- a/app/src/main/java/fr/gaulupeau/apps/Poche/ui/Themes.java +++ b/app/src/main/java/fr/gaulupeau/apps/Poche/ui/Themes.java @@ -9,6 +9,8 @@ import fr.gaulupeau.apps.InThePoche.R; import fr.gaulupeau.apps.Poche.App; +import android.content.Context; +import android.content.res.Configuration; public class Themes { @@ -28,23 +30,38 @@ public static Theme getCurrentTheme() { return theme; } + public static Theme getResolvedTheme(Context context) { + if (App.getSettings().isAutoThemeEnabled()) { + int currentNightMode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; + if (currentNightMode == Configuration.UI_MODE_NIGHT_YES) { + return Theme.DARK; + } else { + return Theme.LIGHT; + } + } + return theme; + } + public static void applyTheme(Activity activity) { applyTheme(activity, true); } public static void applyTheme(Activity activity, boolean actionBar) { - activity.setTheme(actionBar ? theme.getResId() : theme.getNoActionBarResId()); - appliedThemes.put(activity, theme); + Theme resolvedTheme = getResolvedTheme(activity); + activity.setTheme(actionBar ? resolvedTheme.getResId() : resolvedTheme.getNoActionBarResId()); + appliedThemes.put(activity, resolvedTheme); } public static void applyDialogTheme(Activity activity) { - activity.setTheme(theme.getDialogResId()); - appliedThemes.put(activity, theme); + Theme resolvedTheme = getResolvedTheme(activity); + activity.setTheme(resolvedTheme.getDialogResId()); + appliedThemes.put(activity, resolvedTheme); } public static void checkTheme(Activity activity) { Theme appliedTheme = appliedThemes.get(activity); - if(appliedTheme != theme) activity.recreate(); + Theme resolvedTheme = getResolvedTheme(activity); + if(appliedTheme != resolvedTheme) activity.recreate(); } public enum Theme { diff --git a/app/src/main/res/values/strings-preference-keys.xml b/app/src/main/res/values/strings-preference-keys.xml index ef323c1e4..6fc25ff65 100644 --- a/app/src/main/res/values/strings-preference-keys.xml +++ b/app/src/main/res/values/strings-preference-keys.xml @@ -28,6 +28,7 @@ ui.lists.sortOrder ui.tagList.sortOrder ui.theme + ui.theme.auto ui.volumeButtonsScrolling.enabled ui.tapToScroll.enabled ui.screenScrolling diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 668194286..9108e7895 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -201,6 +201,8 @@ UI App theme + Auto dark mode + Switch between light and dark theme based on system settings Article text size (%) Serif typeface Serif font for articles diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 5940631ac..b3e0926ed 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -79,6 +79,11 @@ android:title="@string/pref_name_ui_theme" android:dialogTitle="@string/pref_name_ui_theme" android:defaultValue="LIGHT"/> + Date: Sun, 19 Apr 2026 16:09:48 +0200 Subject: [PATCH 2/3] Added support for configuring custom light and dark themes when using automatic theme switching. --- .../gaulupeau/apps/Poche/data/Settings.java | 30 ++++++++++++++++ .../fr/gaulupeau/apps/Poche/ui/Themes.java | 30 +++++++++++----- .../ui/preferences/SettingsActivity.java | 36 +++++++++++++++++++ .../res/values/strings-preference-keys.xml | 2 ++ app/src/main/res/values/strings.xml | 4 +++ app/src/main/res/xml/preferences.xml | 14 ++++++++ 6 files changed, 107 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/fr/gaulupeau/apps/Poche/data/Settings.java b/app/src/main/java/fr/gaulupeau/apps/Poche/data/Settings.java index 29b1f0822..2f3eafac6 100644 --- a/app/src/main/java/fr/gaulupeau/apps/Poche/data/Settings.java +++ b/app/src/main/java/fr/gaulupeau/apps/Poche/data/Settings.java @@ -456,6 +456,36 @@ public void setAutoThemeEnabled(boolean value) { setBoolean(R.string.pref_key_ui_theme_auto, value); } + public Themes.Theme getAutoLightTheme() { + String themeName = getString(R.string.pref_key_ui_theme_auto_light); + Themes.Theme theme = null; + if(themeName != null) { + try { + theme = Themes.Theme.valueOf(themeName); + } catch(IllegalArgumentException ignored) {} + } + return theme != null ? theme : Themes.Theme.LIGHT; + } + + public void setAutoLightTheme(Themes.Theme theme) { + setString(R.string.pref_key_ui_theme_auto_light, theme.toString()); + } + + public Themes.Theme getAutoDarkTheme() { + String themeName = getString(R.string.pref_key_ui_theme_auto_dark); + Themes.Theme theme = null; + if(themeName != null) { + try { + theme = Themes.Theme.valueOf(themeName); + } catch(IllegalArgumentException ignored) {} + } + return theme != null ? theme : Themes.Theme.DARK; + } + + public void setAutoDarkTheme(Themes.Theme theme) { + setString(R.string.pref_key_ui_theme_auto_dark, theme.toString()); + } + public boolean isVolumeButtonsScrollingEnabled() { return getBoolean(R.string.pref_key_ui_volumeButtonsScrolling_enabled, false); } diff --git a/app/src/main/java/fr/gaulupeau/apps/Poche/ui/Themes.java b/app/src/main/java/fr/gaulupeau/apps/Poche/ui/Themes.java index ee806afc3..544a9deaa 100644 --- a/app/src/main/java/fr/gaulupeau/apps/Poche/ui/Themes.java +++ b/app/src/main/java/fr/gaulupeau/apps/Poche/ui/Themes.java @@ -34,9 +34,9 @@ public static Theme getResolvedTheme(Context context) { if (App.getSettings().isAutoThemeEnabled()) { int currentNightMode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; if (currentNightMode == Configuration.UI_MODE_NIGHT_YES) { - return Theme.DARK; + return App.getSettings().getAutoDarkTheme(); } else { - return Theme.LIGHT; + return App.getSettings().getAutoLightTheme(); } } return theme; @@ -69,55 +69,67 @@ public enum Theme { R.string.themeName_light, R.style.LightTheme, R.style.LightTheme_NoActionBar, - R.style.DialogTheme + R.style.DialogTheme, + false ), LIGHT_CONTRAST( R.string.themeName_light_contrast, R.style.LightThemeContrast, R.style.LightThemeContrast_NoActionBar, - R.style.DialogTheme + R.style.DialogTheme, + false ), E_INK( R.string.themeName_eink, R.style.LightThemeContrast, R.style.LightThemeContrast_NoActionBar, - R.style.DialogTheme + R.style.DialogTheme, + false ), DARK( R.string.themeName_dark, R.style.DarkTheme, R.style.DarkTheme_NoActionBar, - R.style.DialogThemeDark + R.style.DialogThemeDark, + true ), DARK_CONTRAST( R.string.themeName_dark_contrast, R.style.DarkThemeContrast, R.style.DarkThemeContrast_NoActionBar, - R.style.DialogThemeDark + R.style.DialogThemeDark, + true ), SOLARIZED( R.string.themeName_solarized, R.style.SolarizedTheme, R.style.SolarizedTheme_NoActionBar, - R.style.DialogTheme + R.style.DialogTheme, + true ); private int nameId; private int resId; private int noActionBarResId; private int dialogResId; + private boolean isDark; Theme(@StringRes int nameId, @StyleRes int resId, - @StyleRes int noActionBarResId, @StyleRes int dialogResId) { + @StyleRes int noActionBarResId, @StyleRes int dialogResId, boolean isDark) { this.nameId = nameId; this.resId = resId; this.noActionBarResId = noActionBarResId; this.dialogResId = dialogResId; + this.isDark = isDark; + } + + public boolean isDark() { + return isDark; } public @StringRes int getNameId() { diff --git a/app/src/main/java/fr/gaulupeau/apps/Poche/ui/preferences/SettingsActivity.java b/app/src/main/java/fr/gaulupeau/apps/Poche/ui/preferences/SettingsActivity.java index 8451f8134..63e65dbe2 100644 --- a/app/src/main/java/fr/gaulupeau/apps/Poche/ui/preferences/SettingsActivity.java +++ b/app/src/main/java/fr/gaulupeau/apps/Poche/ui/preferences/SettingsActivity.java @@ -77,6 +77,8 @@ public static class SettingsFragment extends PreferenceFragment R.string.pref_key_connection_api_clientID, R.string.pref_key_connection_api_clientSecret, R.string.pref_key_ui_theme, + R.string.pref_key_ui_theme_auto_light, + R.string.pref_key_ui_theme_auto_dark, R.string.pref_key_ui_article_fontSize, R.string.pref_key_ui_screenScrolling_percent, R.string.pref_key_autoSync_interval, @@ -147,6 +149,38 @@ public void onCreate(Bundle savedInstanceState) { themeListPreference.setEntryValues(themeEntryValues); } + ListPreference autoLightThemePreference = (ListPreference)findPreference( + getString(R.string.pref_key_ui_theme_auto_light)); + if(autoLightThemePreference != null) { + Themes.Theme[] themes = Themes.Theme.values(); + List entries = new ArrayList<>(); + List values = new ArrayList<>(); + for (Themes.Theme t : themes) { + if (!t.isDark()) { + entries.add(getString(t.getNameId())); + values.add(t.toString()); + } + } + autoLightThemePreference.setEntries(entries.toArray(new String[0])); + autoLightThemePreference.setEntryValues(values.toArray(new String[0])); + } + + ListPreference autoDarkThemePreference = (ListPreference)findPreference( + getString(R.string.pref_key_ui_theme_auto_dark)); + if(autoDarkThemePreference != null) { + Themes.Theme[] themes = Themes.Theme.values(); + List entries = new ArrayList<>(); + List values = new ArrayList<>(); + for (Themes.Theme t : themes) { + if (t.isDark()) { + entries.add(getString(t.getNameId())); + values.add(t.toString()); + } + } + autoDarkThemePreference.setEntries(entries.toArray(new String[0])); + autoDarkThemePreference.setEntryValues(values.toArray(new String[0])); + } + ListPreference autoSyncIntervalListPreference = (ListPreference)findPreference( getString(R.string.pref_key_autoSync_interval)); if(autoSyncIntervalListPreference != null) { @@ -715,6 +749,8 @@ private void updateSummary(int keyResID) { break; case R.string.pref_key_ui_theme: + case R.string.pref_key_ui_theme_auto_light: + case R.string.pref_key_ui_theme_auto_dark: case R.string.pref_key_autoSync_interval: case R.string.pref_key_autoSync_type: setListSummaryFromContent(key); diff --git a/app/src/main/res/values/strings-preference-keys.xml b/app/src/main/res/values/strings-preference-keys.xml index 6fc25ff65..3aa900f41 100644 --- a/app/src/main/res/values/strings-preference-keys.xml +++ b/app/src/main/res/values/strings-preference-keys.xml @@ -29,6 +29,8 @@ ui.tagList.sortOrder ui.theme ui.theme.auto + ui.theme.auto.light + ui.theme.auto.dark ui.volumeButtonsScrolling.enabled ui.tapToScroll.enabled ui.screenScrolling diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9108e7895..7519b106f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -203,6 +203,10 @@ App theme Auto dark mode Switch between light and dark theme based on system settings + Auto light theme + Theme to use when system is in light mode + Auto dark theme + Theme to use when system is in dark mode Article text size (%) Serif typeface Serif font for articles diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index b3e0926ed..9bc01f228 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -84,6 +84,20 @@ android:title="@string/pref_name_ui_theme_auto" android:summary="@string/pref_desc_ui_theme_auto" android:defaultValue="false"/> + + Date: Sun, 19 Apr 2026 16:13:07 +0200 Subject: [PATCH 3/3] Implemented the fix in SettingsActivity.java to ensure that the theme updates immediately when you change the auto theme settings. --- .../apps/Poche/ui/preferences/SettingsActivity.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/java/fr/gaulupeau/apps/Poche/ui/preferences/SettingsActivity.java b/app/src/main/java/fr/gaulupeau/apps/Poche/ui/preferences/SettingsActivity.java index 63e65dbe2..e0b2c95cc 100644 --- a/app/src/main/java/fr/gaulupeau/apps/Poche/ui/preferences/SettingsActivity.java +++ b/app/src/main/java/fr/gaulupeau/apps/Poche/ui/preferences/SettingsActivity.java @@ -431,6 +431,12 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin themeChanged = true; break; + case R.string.pref_key_ui_theme_auto: + case R.string.pref_key_ui_theme_auto_light: + case R.string.pref_key_ui_theme_auto_dark: + themeChanged = true; + break; + case R.string.pref_key_autoSync_enabled: autoSyncChanged = true; break;