mirror of
https://codeberg.org/OpenTracksApp/OpenTracks.git
synced 2026-09-30 16:52:21 +02:00
Themes: use separate themes for DayNight/OLED/DynamicColors.
Fixes #2123.
This commit is contained in:
@@ -79,8 +79,7 @@ limitations under the License.
|
||||
android:hasFragileUserData="false"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/OpenTracksTheme">
|
||||
android:supportsRtl="true">
|
||||
|
||||
<activity
|
||||
android:name=".publicapi.StartRecording"
|
||||
|
||||
@@ -37,9 +37,7 @@ public abstract class AbstractActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
if (PreferencesUtils.shouldApplyOledTheme()) {
|
||||
setTheme(R.style.OpenTracksThemeOled);
|
||||
}
|
||||
PreferencesUtils.applyTheme(this);
|
||||
|
||||
EdgeToEdge.enable(this);
|
||||
|
||||
|
||||
@@ -6,8 +6,6 @@ import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.android.material.color.DynamicColors;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import de.dennisguse.opentracks.settings.PreferencesUtils;
|
||||
@@ -34,11 +32,7 @@ public class Startup extends Application {
|
||||
// Set default values of preferences on first start.
|
||||
PreferencesUtils.resetPreferences(this, false);
|
||||
PreferencesUtils.applyDefaultUnit();
|
||||
PreferencesUtils.applyNightMode();
|
||||
|
||||
if (PreferencesUtils.shouldUseDynamicColors()) {
|
||||
DynamicColors.applyToActivitiesIfAvailable(this);
|
||||
}
|
||||
PreferencesUtils.applyNightModeAndDynamicColors(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package de.dennisguse.opentracks.settings;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
@@ -30,6 +31,8 @@ import androidx.annotation.VisibleForTesting;
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import com.google.android.material.color.DynamicColors;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -338,11 +341,6 @@ public class PreferencesUtils {
|
||||
return getBoolean(R.string.chart_display_heart_rate_key, DEFAULT);
|
||||
}
|
||||
|
||||
public static boolean shouldUseDynamicColors() {
|
||||
final boolean DEFAULT = resources.getBoolean(R.bool.settings_ui_dynamic_colors_default);
|
||||
return getBoolean(R.string.settings_ui_dynamic_colors_key, DEFAULT);
|
||||
}
|
||||
|
||||
public static boolean shouldVoiceAnnouncementOnDeviceSpeaker() {
|
||||
final boolean DEFAULT = resources.getBoolean(R.bool.voice_on_device_speaker_default);
|
||||
return getBoolean(R.string.voice_on_device_speaker_key, DEFAULT);
|
||||
@@ -705,7 +703,7 @@ public class PreferencesUtils {
|
||||
public static TrackFileFormat getExportTrackFileFormat() {
|
||||
final String TRACKFILEFORMAT_NAME_DEFAULT = getString(R.string.export_trackfileformat_default, null);
|
||||
String trackFileFormatName = getString(R.string.export_trackfileformat_key, TRACKFILEFORMAT_NAME_DEFAULT);
|
||||
return Arrays.stream(TrackFileFormat.values())
|
||||
return Arrays.stream(TrackFileFormat.values())
|
||||
.filter(format -> format.getPreferenceId().equals(trackFileFormatName))
|
||||
.findFirst().orElse(TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA_AND_PICTURES);
|
||||
}
|
||||
@@ -715,30 +713,62 @@ public class PreferencesUtils {
|
||||
return getBoolean(R.string.import_prevent_reimport_key, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return * {@link androidx.appcompat.app.AppCompatDelegate}.MODE_*
|
||||
* * 3: Night OLED friendly
|
||||
*/
|
||||
private static String getUiMode() {
|
||||
final String defaultValue = getKey(R.string.night_mode_default);
|
||||
final String value = getString(R.string.night_mode_key, defaultValue);
|
||||
|
||||
return value;
|
||||
record ThemeConfig(int themeResourceId, int dayNight, boolean dynamicColor) {
|
||||
}
|
||||
|
||||
public static boolean shouldApplyOledTheme() {
|
||||
return resources.getString(R.string.night_mode_night_oled_value)
|
||||
.equals(getUiMode());
|
||||
private static ThemeConfig getThemeMode() {
|
||||
final String defaultValue = getKey(R.string.theme_default);
|
||||
final String value = getString(R.string.theme_key, defaultValue);
|
||||
|
||||
switch (value) {
|
||||
case "0" -> {
|
||||
return new ThemeConfig(R.style.DayNightColorTheme, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM, false);
|
||||
}
|
||||
case "1" -> {
|
||||
return new ThemeConfig(R.style.DayNightDynamicTheme, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM, true);
|
||||
}
|
||||
case "2" -> {
|
||||
return new ThemeConfig(R.style.DayNightColorTheme, AppCompatDelegate.MODE_NIGHT_NO, false);
|
||||
}
|
||||
case "3" -> {
|
||||
return new ThemeConfig(R.style.DayNightDynamicTheme, AppCompatDelegate.MODE_NIGHT_NO, true);
|
||||
}
|
||||
case "4" -> {
|
||||
return new ThemeConfig(R.style.DayNightColorTheme, AppCompatDelegate.MODE_NIGHT_YES, false);
|
||||
}
|
||||
case "5" -> {
|
||||
return new ThemeConfig(R.style.DayNightDynamicTheme, AppCompatDelegate.MODE_NIGHT_YES, true);
|
||||
}
|
||||
case "6" -> {
|
||||
return new ThemeConfig(R.style.NightOledColorTheme, AppCompatDelegate.MODE_NIGHT_YES, false);
|
||||
}
|
||||
case "7" -> {
|
||||
return new ThemeConfig(R.style.NightOledDynamicTheme, AppCompatDelegate.MODE_NIGHT_YES, true);
|
||||
}
|
||||
|
||||
default -> {
|
||||
return new ThemeConfig(R.style.DayNightColorTheme, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void applyTheme(Context context) {
|
||||
context.setTheme(getThemeMode().themeResourceId());
|
||||
}
|
||||
|
||||
public static void applyNightMode() {
|
||||
String uiMode = getUiMode();
|
||||
if (resources.getString(R.string.night_mode_night_oled_value)
|
||||
.equals(uiMode)) {
|
||||
return;
|
||||
}
|
||||
ThemeConfig themeConfig = getThemeMode();
|
||||
|
||||
AppCompatDelegate.setDefaultNightMode(Integer.parseInt(uiMode));
|
||||
AppCompatDelegate.setDefaultNightMode(themeConfig.dayNight);
|
||||
}
|
||||
|
||||
public static void applyNightModeAndDynamicColors(Application application) {
|
||||
ThemeConfig themeConfig = getThemeMode();
|
||||
|
||||
applyNightMode();
|
||||
|
||||
if (application != null && themeConfig.dynamicColor)
|
||||
DynamicColors.applyToActivitiesIfAvailable(application);
|
||||
}
|
||||
|
||||
public static void resetPreferences(Context context, boolean readAgain) {
|
||||
|
||||
@@ -2,7 +2,6 @@ package de.dennisguse.opentracks.settings;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.widget.Toast;
|
||||
|
||||
@@ -15,7 +14,7 @@ import de.dennisguse.opentracks.R;
|
||||
public class UserInterfaceSettingsFragment extends PreferenceFragmentCompat {
|
||||
|
||||
private final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (sharedPreferences, key) -> {
|
||||
if (PreferencesUtils.isKey(R.string.night_mode_key, key)) {
|
||||
if (PreferencesUtils.isKey(R.string.theme_key, key)) {
|
||||
getActivity().runOnUiThread(() -> {
|
||||
PreferencesUtils.applyNightMode();
|
||||
Toast.makeText(getContext(), R.string.settings_theme_switch_restart, Toast.LENGTH_LONG).show();
|
||||
@@ -33,9 +32,6 @@ public class UserInterfaceSettingsFragment extends PreferenceFragmentCompat {
|
||||
startActivity(intent);
|
||||
return true;
|
||||
});
|
||||
|
||||
Preference dynamicColors = findPreference(getString(R.string.settings_ui_dynamic_colors_key));
|
||||
dynamicColors.setEnabled(Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<style name="OpenTracksTheme" parent="Theme.Material3.DayNight.NoActionBar">
|
||||
<!-- Material3 tech documentation; https://github.com/material-components/material-components-android/blob/master/docs/components/ -->
|
||||
|
||||
<item name="colorPrimary">@color/opentracks</item>
|
||||
<item name="colorSecondary">@color/opentracks</item>
|
||||
|
||||
<!-- Material3 https://github.com/material-components/material-components-android/issues/2828#issuecomment-1187563903 -->
|
||||
<item name="switchPreferenceCompatStyle">@style/MaterialSwitchPreferenceCompat</item>
|
||||
|
||||
<item name="android:statusBarColor">@color/oled_friendly</item>
|
||||
<item name="android:windowLightStatusBar">false</item>
|
||||
<item name="android:navigationBarColor">@color/oled_friendly</item>
|
||||
|
||||
|
||||
<item name="bottomAppBarStyle">@style/Widget.OpenTracks.BottomAppBar</item>
|
||||
<item name="floatingActionButtonStyle">@style/Widget.OpenTracks.FloatingActionButton</item>
|
||||
|
||||
<item name="windowActionModeOverlay">true</item>
|
||||
</style>
|
||||
|
||||
<style name="SplashTheme" parent="Theme.SplashScreen">
|
||||
<item name="windowSplashScreenBackground">@color/splashscreen_background</item>
|
||||
|
||||
<item name="windowSplashScreenAnimatedIcon">@drawable/ic_logo_color_108dp</item>
|
||||
<item name="postSplashScreenTheme">@style/OpenTracksTheme</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.OpenTracks.BottomAppBar" parent="Widget.Material3.BottomAppBar">
|
||||
<item name="materialThemeOverlay">@style/ThemeOverlay.OpenTracks.BottomAppBar</item>
|
||||
</style>
|
||||
|
||||
<style name="ThemeOverlay.OpenTracks.BottomAppBar" parent="">
|
||||
<item name="colorPrimary">@color/oled_friendly</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
@@ -270,8 +270,7 @@
|
||||
|
||||
<!-- User Interface Settings -->
|
||||
|
||||
<string name="settings_ui_dynamic_colors_key" translatable="false">uiDynamicColors</string>
|
||||
<bool name="settings_ui_dynamic_colors_default" translatable="false">false</bool>
|
||||
<string name="deleted20250703" translatable="false">uiDynamicColors</string> <!-- DELETED -->
|
||||
|
||||
<!-- Recording Settings -->
|
||||
<string name="stats_show_on_lockscreen_while_recording_key" translatable="false">trackdetail_show_on_lockscreen_while_recording</string>
|
||||
@@ -301,23 +300,36 @@
|
||||
<string name="locale_key" translatable="false">localeKey</string>
|
||||
|
||||
<!-- androidx.appcompat.app.AppCompatDelegate.setDefaultNightMode() -->
|
||||
<string name="night_mode_key" translatable="false">nightMode</string>
|
||||
<string name="night_mode_default" translatable="false">@string/night_mode_system_value</string>
|
||||
<string name="night_mode_no_value" translatable="false">1</string>
|
||||
<string name="night_mode_yes_value" translatable="false">2</string>
|
||||
<string name="night_mode_night_oled_value" translatable="false">3</string>
|
||||
<string name="night_mode_system_value" translatable="false">-1</string>
|
||||
<string name="theme_key" translatable="false">nightMode</string>
|
||||
<string name="theme_default" translatable="false">@string/theme_daynight_value</string>
|
||||
<string name="theme_daynight_value" translatable="false">0</string>
|
||||
<string name="theme_daynight_dynamic_value" translatable="false">1</string>
|
||||
<string name="theme_day_value" translatable="false">2</string>
|
||||
<string name="theme_day_dynamic_value" translatable="false">3</string>
|
||||
<string name="theme_night_value" translatable="false">4</string>
|
||||
<string name="theme_night_dynamic_value" translatable="false">5</string>
|
||||
<string name="theme_oled_value" translatable="false">6</string>
|
||||
<string name="theme_oled_dynamic_value" translatable="false">7</string>
|
||||
<string-array name="night_mode_values">
|
||||
<item>@string/night_mode_system_value</item>
|
||||
<item>@string/night_mode_no_value</item>
|
||||
<item>@string/night_mode_yes_value</item>
|
||||
<item>@string/night_mode_night_oled_value</item>
|
||||
<item>@string/theme_daynight_value</item>
|
||||
<item>@string/theme_daynight_dynamic_value</item>
|
||||
<item>@string/theme_day_value</item>
|
||||
<item>@string/theme_day_dynamic_value</item>
|
||||
<item>@string/theme_night_value</item>
|
||||
<item>@string/theme_night_dynamic_value</item>
|
||||
<item>@string/theme_oled_value</item>
|
||||
<item>@string/theme_oled_dynamic_value</item>
|
||||
</string-array>
|
||||
<string-array name="night_mode_options">
|
||||
<!-- TODO: rename night_mode to theme and night_oled to oled -->
|
||||
<item>@string/settings_night_mode_option_system</item>
|
||||
<item>@string/settings_night_mode_option_system_dynamic</item>
|
||||
<item>@string/settings_night_mode_option_day</item>
|
||||
<item>@string/settings_night_mode_option_day_dynamic</item>
|
||||
<item>@string/settings_night_mode_option_night</item>
|
||||
<item>@string/settings_night_mode_option_night_dynamic</item>
|
||||
<item>@string/settings_night_mode_option_night_oled</item>
|
||||
<item>@string/settings_night_mode_option_night_oled_dynamic</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Stats layout customization -->
|
||||
|
||||
@@ -380,9 +380,13 @@ limitations under the License.
|
||||
<string name="settings_locale_system_default">System default</string>
|
||||
<string name="settings_night_mode_title">UI Theme</string>
|
||||
<string name="settings_night_mode_option_system">System</string>
|
||||
<string name="settings_night_mode_option_system_dynamic">System (DynamicColor)</string>
|
||||
<string name="settings_night_mode_option_day">Day</string>
|
||||
<string name="settings_night_mode_option_day_dynamic">Day (DynamicColor)</string>
|
||||
<string name="settings_night_mode_option_night">Night</string>
|
||||
<string name="settings_night_mode_option_night_oled">Night (OLED friendly)</string>
|
||||
<string name="settings_night_mode_option_night_dynamic">Night (DynamicColor)</string>
|
||||
<string name="settings_night_mode_option_night_oled">OLED friendly</string>
|
||||
<string name="settings_night_mode_option_night_oled_dynamic">OLED friendly (DynamicColor)</string>
|
||||
<string name="settings_announcements_totaltime_frequency">Time interval</string>
|
||||
<string name="settings_announcements_distance_frequency">Lap length</string>
|
||||
<string name="settings_announcements_average_heart_rate">Average heart rate</string>
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<style name="OpenTracksTheme" parent="Theme.Material3.DayNight.NoActionBar">
|
||||
<item name="colorPrimary">@color/opentracks</item>
|
||||
<item name="colorSecondary">@color/opentracks</item>
|
||||
|
||||
<style name="DayNightDynamicTheme" parent="Theme.Material3.DayNight.NoActionBar">
|
||||
<!-- Material3 https://github.com/material-components/material-components-android/issues/2828#issuecomment-1187563903 -->
|
||||
<item name="switchPreferenceCompatStyle">@style/MaterialSwitchPreferenceCompat</item>
|
||||
|
||||
@@ -26,19 +23,12 @@
|
||||
<item name="actionBarSize">88dp</item>
|
||||
</style>
|
||||
|
||||
<style name="SplashTheme" parent="Theme.SplashScreen">
|
||||
<item name="windowSplashScreenAnimatedIcon">@drawable/ic_logo_color_108dp</item>
|
||||
<item name="postSplashScreenTheme">@style/OpenTracksTheme</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.OpenTracks.BottomAppBar" parent="Widget.Material3.BottomAppBar">
|
||||
<item name="backgroundTint">?attr/colorSurfaceContainer</item>
|
||||
</style>
|
||||
|
||||
<style name="OpenTracksThemeOled" parent="Theme.Material3.Dark.NoActionBar">
|
||||
<style name="DayNightColorTheme" parent="DayNightDynamicTheme">
|
||||
<item name="colorPrimary">@color/opentracks</item>
|
||||
<item name="colorSecondary">@color/opentracks</item>
|
||||
</style>
|
||||
|
||||
<style name="NightOledDynamicTheme" parent="Theme.Material3.Dark.NoActionBar">
|
||||
<!-- Material3 https://github.com/material-components/material-components-android/issues/2828#issuecomment-1187563903 -->
|
||||
<item name="switchPreferenceCompatStyle">@style/MaterialSwitchPreferenceCompat</item>
|
||||
|
||||
@@ -54,16 +44,41 @@
|
||||
<!-- Differences to OpenTracksTheme -->
|
||||
<item name="bottomAppBarStyle">@style/Widget.OpenTracks.BottomAppBarOled</item>
|
||||
|
||||
<item name="android:statusBarColor">@android:color/black</item>
|
||||
<item name="android:statusBarColor">@color/oled_friendly</item>
|
||||
<item name="android:windowLightStatusBar">false</item>
|
||||
<item name="android:navigationBarColor">@android:color/black</item>
|
||||
<item name="android:navigationBarColor">@color/oled_friendly</item>
|
||||
|
||||
<item name="colorSurface">@android:color/black</item>
|
||||
<item name="colorSurfaceContainer">@android:color/black</item>
|
||||
<item name="android:windowBackground">@android:color/black</item>
|
||||
<item name="colorSurface">@color/oled_friendly</item>
|
||||
<item name="colorSurfaceContainer">@color/oled_friendly</item>
|
||||
<item name="colorSurfaceDim">@color/oled_friendly</item>
|
||||
<item name="backgroundColor">@color/oled_friendly</item>
|
||||
<item name="android:windowBackground">@color/oled_friendly</item>
|
||||
|
||||
<!-- Material3-related: otherwise the actionbar does not overlay the SearchBar completely (with AppBarLayout) -->
|
||||
<item name="actionBarSize">88dp</item>
|
||||
</style>
|
||||
|
||||
<style name="NightOledColorTheme" parent="NightOledDynamicTheme">
|
||||
<item name="colorPrimary">@color/opentracks</item>
|
||||
<item name="colorSecondary">@color/opentracks</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.OpenTracks.BottomAppBarOled" parent="Widget.Material3.BottomAppBar">
|
||||
<item name="backgroundTint">@android:color/transparent</item>
|
||||
<item name="backgroundTint">@color/oled_friendly</item>
|
||||
</style>
|
||||
|
||||
<style name="SplashTheme" parent="Theme.SplashScreen">
|
||||
<item name="windowSplashScreenBackground">@color/splashscreen_background</item>
|
||||
|
||||
<item name="windowSplashScreenAnimatedIcon">@drawable/ic_logo_color_108dp</item>
|
||||
<item name="postSplashScreenTheme">@style/DayNightColorTheme</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.OpenTracks.BottomAppBar" parent="Widget.Material3.BottomAppBar">
|
||||
<item name="materialThemeOverlay">@style/ThemeOverlay.OpenTracks.BottomAppBar</item>
|
||||
</style>
|
||||
|
||||
<style name="ThemeOverlay.OpenTracks.BottomAppBar" parent="">
|
||||
<item name="colorPrimary">@color/oled_friendly</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
@@ -11,19 +11,13 @@
|
||||
app:useSimpleSummaryProvider="true" />
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="@string/night_mode_default"
|
||||
android:defaultValue="@string/theme_default"
|
||||
android:entries="@array/night_mode_options"
|
||||
android:entryValues="@array/night_mode_values"
|
||||
android:key="@string/night_mode_key"
|
||||
android:key="@string/theme_key"
|
||||
android:title="@string/settings_night_mode_title"
|
||||
app:useSimpleSummaryProvider="true" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="@bool/settings_ui_dynamic_colors_default"
|
||||
android:key="@string/settings_ui_dynamic_colors_key"
|
||||
android:summary="@string/settings_ui_dynamic_colors_summary"
|
||||
android:title="@string/settings_ui_dynamic_colors_title" />
|
||||
|
||||
<PreferenceCategory app:title="@string/settings_recording_title">
|
||||
|
||||
<Preference
|
||||
|
||||
Reference in New Issue
Block a user