I'd like to make a SettingsActivity
to let the user personalize the appearence of the app.
In this activity the user can choose to keep the app in a "light theme" (that means for example white backgrounds with black texts) or a "dark theme", the opposite colours of light theme to favour the night use.
How could it be done?
I was thinking about creating different layouts in xml for each theme.
EDITS
The images below are examples of SettingsActivity
, I'd like to change the appearence for the whole app, not single activity.
This is how I've done it for my app. I'm sure my approach can help.
Set up your Light and Dark themes in styles.xml like this:
<!-- Use this theme in Manifest by default -->
<style name="MyLightTheme" parent="Base.AppTheme.Light"></style>
<!-- Base light theme containing all styles -->
<style name="Base.AppTheme.Light" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
... Other styles
</style>
<!-- Use this to switch to Dark theme -->
<style name="MyDarkTheme" parent="Base.AppTheme.Dark"></style>
<!-- Base dark theme containing all styles -->
<style name="Base.AppTheme.Dark" parent="Theme.AppCompat">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
... Other styles
</style>
Since you're controlling Theme change via a preference, register a preference change listener in your PreferenceFragment.
PreferenceManager.getDefaultSharedPreferences(getActivity()).registerOnSharedPreferenceChangeListener(this);
Implement onSharedPreferenceChanged():
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(getString(R.string.pref_key_nighttheme))) {
if (sharedPreferences.getBoolean(getString(R.string.pref_key_nighttheme), false)) {
// Night theme enabled
getActivity().setTheme(R.style.MyDarkTheme);
getActivity().getApplication().setTheme(R.style.MyDarkTheme);
darkTheme = true;
} else {
getActivity().setTheme(R.style.MyLightTheme);
getActivity().getApplication().setTheme(R.style.MyLightTheme);
darkTheme = false;
}
getActivity().recreate(); // This is important. It allows the theme change to take effect.
}
}
Be sure to recreate your MainActivity in onResume() if Back Navigation leads to MainActivity.
Additionally, you must check for the current theme in EVERY Activity, BEFORE super() is called in onCreate().
isThemeDark = setDarkTheme(this);
setDarkTheme() is a helper I've created which checks the current Theme via SharedPreference. It checks if a Theme change is necessary or not.
public static boolean setDarkTheme(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean isDarkTheme = prefs.getBoolean(context.getString(R.string.pref_key_nighttheme), false);
context.setTheme(SettingsActivity.darkTheme ? R.style.MyDarkTheme : R.style.MyLightTheme);
return isDarkTheme;
}
Here's how Night mode works in my app Newslet:
UPDATE: Android now officially supports Night Mode via its AppCompat DayNight Theme. Here's a tutorial on the same.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With