I have a settings PreferenceFragment
that allows the user to select a theme. The user can select a dark or light theme. After selecting a theme the user presses the back button to return to the previous fragment. This called the containing activity's onCreate method where the theme is read and applied. However the theme is not applied correctly, Switching from Holo.Light to Holo.Dark changes the background colour, action bar etc but does not change the text resulting in faded, hard to read text. Any ideas what I am doing wrong? Everything I have read says that the theme should be applied in the onCreate method and that is what I am doing.
Thanks in advance for your help.
EDIT
As requested here is the relevant code.
public class MainActivity extends Activity {
private ActionBarDrawerToggle mSlideMenuToggle;
private boolean isDarkTheme;
private static final String InitializedKey = "initialized";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
applySettings();
setContentView(R.layout.activity_main);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mSlideMenuToggle.onOptionsItemSelected(item)) {
return true;
} else if (item.getItemId() == R.id.menu_settings) {
getFragmentManager().beginTransaction()
.replace(R.id.content_frame, new SettingsFragment())
.addToBackStack(null)
.commit();
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
private void applySettings() {
isDarkTheme = PreferenceManager.getDefaultSharedPreferences(this).getString(SettingsFragment.ThemeSetting, null).equals("1");
if (isDarkTheme) {
setTheme(android.R.style.Theme_Holo);
} else {
setTheme(android.R.style.Theme_Holo_Light);
}
}
The onCreate
method applies the current theme to the activity by calling applySettings
. The options menu allows for a SettingsFragment
to be created.
public class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
public static final String ThemeSetting = "isDarkTheme";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(ThemeSetting)) {
String[] themes = getResources().getStringArray(R.array.isDarkThemeStrings);
findPreference(key).setSummary(sharedPreferences.getString(key, "").equals("0") ? themes[0] : themes[1]);
}
}
@Override
public void onResume() {
super.onResume();
PreferenceManager.getDefaultSharedPreferences(getActivity()).registerOnSharedPreferenceChangeListener(this);
}
@Override
public void onPause() {
super.onPause();
PreferenceManager.getDefaultSharedPreferences(getActivity()).unregisterOnSharedPreferenceChangeListener(this);
}
}
The SettingsFragment
has one setting, Theme which can have one of two values, Dark or Light. The user picks one and then hits the back button. This causes the onCreate
method of the MainActivity
to be called, again applying the settings but not correctly.
Anyone? I feel like that once the theme is changed in the SettingsFragment
and then the back button is pressed the theme should be applied to MainActivity
but it is not. Most elements change but the text stays dark (going from Holo.Light to Holo.Dark).
I think I can help you with this. I spent a lot of time over the last few months working on the exact same thing for my app.
The above poster isn't exactly correct. You need to set the theme in onCreate()
before views are instantiated -- before setContentView()
. When super.onCreate()
is called isn't important. I don't see setContentView()
in your code above, so I'm wondering if you removed it?
However, if your activity is being themed correctly when you rotate (because it is destroyed and recreated on orientation change) then there's nothing wrong with how you're setting the theme. Instead, I'm inclined to think you're mistaken about onCreate()
being called when you exit the SettingsFragment.
You can force your activity to recreate itself like this:
finish();
startActivity(getIntent());
Please first try setting a breakpoint in your activity's onCreate()
method and confirm whether it's hit on exiting your fragment (I bet it's not.) Then try the code above.