Changing the theme of an android app using preferences - android

I have been trying to get my app to read data from the preferences, and change the theme according to the option selected. I have found many different suggestions on the internet, including here, but have been unable to get it to work.
I have created preferences.xml and arrays.xml, and the user is able to select the theme they want. However, the change is not reflected in the app.
Here are the contents of ActivityMain.java:
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
String userTheme = preferences.getString("prefTheme", "darkab");
if (userTheme.equals("darkab"))
setTheme(R.style.darkab);
else if (userTheme.equals("light"))
setTheme(R.style.light);
else if (userTheme.equals("dark"))
setTheme(R.style.dark);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#SuppressLint("NewApi")
protected void onResume(Bundle savedInstanceState) {
recreate();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
String userTheme = preferences.getString("prefTheme", "darkab");
if (userTheme.equals("darkab"))
setTheme(R.style.darkab);
else if (userTheme.equals("light"))
setTheme(R.style.light);
else {setTheme(R.style.dark);}
super.onResume();
setContentView(R.layout.activity_main);
}
These are the styles I wish to use, as set in styles.xml:
<style name="darkab" parent="android:Theme.Holo.Light.DarkActionBar"></style>
<style name="light" parent="android:Theme.Holo.Light"></style>
<style name="dark" parent="android:Theme.Holo">
And here is my preferences.java file:
public class Preferences extends PreferenceActivity {
#SuppressWarnings("deprecation")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
Any help would be appreciated.

setTheme() is effective only before the layout has been constructed i.e. you should call it before setContentView(). The LayoutInflater resolves theme attributes and accordingly set properties on the View's it creates. To apply a theme on an already running Activity, you would have to re-start the Activity.

I know that I am late but I would like to post a solution here:
Check the full source code here.
This is the code I used when changing theme using preferences..
SharedPreferences pref = PreferenceManager
.getDefaultSharedPreferences(this);
String themeName = pref.getString("prefSyncFrequency3", "Theme1");
if (themeName.equals("Africa")) {
setTheme(R.style.AppTheme);
} else if (themeName.equals("Colorful Beach")) {
//Toast.makeText(this, "set theme", Toast.LENGTH_SHORT).show();
setTheme(R.style.beach);
} else if (themeName.equals("Abstract")) {
//Toast.makeText(this, "set theme", Toast.LENGTH_SHORT).show();
setTheme(R.style.abstract2);
} else if (themeName.equals("Default")) {
setTheme(R.style.defaulttheme);
}
Please note that you have to put the code before setcontentview..

Related

How to automatically switch to dark mode on Android app?

I'm making an Android app. I made another UI for dark mode. So this is what I need; the app will switch to dark theme automatically by the local time. For example, when the sun goes down by the local time, app will be switched to dark mode.
Or another alternative is switching to dark mode by pre-setted time of the day. Hope you understand my problem. Please help me if anyone knows, I prefer the first option to do if it's possible. Thanks in advance.
Maybe you can have a look at AppCompatDelegate.setDefaultNightMode()
you simply define your theme with the parent of DayNight:
<style name="MyTheme" parent="Theme.AppCompat.DayNight">
<!-- Blah blah -->
</style>
and each style with:
<style name="Theme.AppCompat.DayNight"
parent="Theme.AppCompat.Light" />
or
<style name="Theme.AppCompat.DayNight"
parent="Theme.AppCompat" />
and then you can call : AppCompatDelegate.setDefaultNightMode()
with one of these:
MODE_NIGHT_NO. Always use the day (light) theme.
MODE_NIGHT_YES. Always use the night (dark) theme.
MODE_NIGHT_FOLLOW_SYSTEM (default). This setting follows the system’s setting, which on Android Q and above is a system setting (more on this below).
MODE_NIGHT_AUTO_BATTERY. Changes to dark when the device has its ‘Battery Saver’ feature enabled, light otherwise.
MODE_NIGHT_AUTO_TIME & MODE_NIGHT_AUTO. Changes between day/night based on the time of day.
you would typically do this in your own custom application class:
public class MyApplication extends Application {
public void onCreate() {
super.onCreate();
AppCompatDelegate.setDefaultNightMode(
AppCompatDelegate.MODE_NIGHT_YES);
}
}
more info here
Quick way:
public class MainActivity extends BaseActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//restore preferences
SharedPreferences settings0 = this.getSharedPreferences(PREFS_NAME, 0);
lightMode = settings0.getBoolean("key0", true);
//retrieve selected mode
if (lightMode) {
//light mode
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
} else {
//dark mode
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
}
Switch switch0 = findViewById(R.id.Switch0);
switch0.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (darkMode) {
text = "Mode: light";
//light mode
getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_NO);
darkMode = false;
} else {
text = "Mode: dark";
//dark mode
getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_YES);
darkMode = true;
}
//save music preferences
SharedPreferences setting0 = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor0 = setting0.edit();
editor0.putBoolean("key0", darkMode);
editor0.apply();
}
});
}

Apply style setting in Activity immediately

I have an Activity containing a PreferenceFragment. The user can change the app's style (light theme or dark theme) in this Activity. Now I want the change being visible immediately. That means, I want the style of the Activity changing when the user changes the style setting in the PreferenceFragment.
My idea was to listen for the preference change with OnSharedPreferenceChangeListener in the PreferenceFragment and recreate the Activity.
But I do not think this is the right way. So, what is best practice here? Thanks in advance.
UPDATE
Activity:
public class SettingsActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loadSettings();
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new SettingsFragment())
.commit();
}
private void loadSettings() {
SharedPreferences sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(this);
boolean darkTheme =
sharedPreferences.getBoolean(getText(R.string.pref_theme_key).toString(), false);
if (darkTheme) {
setTheme(R.style.DarkTheme);
}
}
}
PreferenceFragment:
public class SettingsFragment extends PreferenceFragment
implements SharedPreferences.OnSharedPreferenceChangeListener {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(getText(R.string.pref_theme_key))) {
// recreate Activity
}
}
}
Preferences:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:defaultValue="false"
android:key="#string/pref_theme_key"
android:title="#string/pref_theme" />
</PreferenceScreen>
I think your approach is correct. Listen for that preference change and then recreate your activity.
Editing for more context:
You should be saving this as a light/dark variant in your preferences and then when your activity is created call setTheme based on this before calling setContentView.

setTheme not changing the theme colors

I know this question was asked few times. but I cant find the problem in my case.
I want to change the theme of the app but my colorPrimary ,colorAccent and etc.. aren't changing.
my MainActivity extends BasicActivity. it looks like this:
public class MainActivity extends BasicActivity {
public static String MY_PREFS = "MY_PREFS";
private SharedPreferences mySharedPreferences;
int prefMode = Activity.MODE_PRIVATE;
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
private ViewPagerAdapter adapter;
private TextView tabOne, tabTwo, tabThree;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
this is my BasicActivity(in this case I made it even simpler to show that the theme is taken from R.style):
public class BasicActivity extends AppCompatActivity {
public static String MY_PREFS = "MY_PREFS";
int prefMode = Activity.MODE_PRIVATE;
protected void onCreate(Bundle savedInstanceState) {
JsonParser parser = new JsonParser(getApplicationContext());
int resourceId = this.getResources().getIdentifier(parser.getThemeID(), "style", this.getPackageName());
setTheme(R.style.c_2ecc71_BC6C2B);
if (android.os.Build.VERSION.SDK_INT >= 19) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
super.onCreate(savedInstanceState);
}
}
and my XML:
<style name="c_2ecc71_BC6C2B" parent="#style/Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#2ecc71</item>
<item name="colorPrimaryDark">#1ebc61</item>
<item name="colorAccent">#BC6C2B</item>
</style>
According to the previous questions this code should work but in my case the views that have colorPrimary in their XML still loading the old theme's colors insted of the new one even though i set the theme before calling setContentView(R.layout.activity_main);
Thanks!
If you use Fragments, they will ignore the value you have set in the onCreate(), if you override the getTheme() method, it will be used within fragments as well:
Answered on different question: Change Activity's theme programmatically
#Override
public Resources.Theme getTheme() {
Resources.Theme theme = super.getTheme();
theme.applyStyle(R.style.c_2ecc71_BC6C2B, true);
return theme;
}
Use it in your MainActivity or your BasicActivity depending on where you want it to apply. You will NOT need to change it in the onCreate anymore.
You are trying to extend one of the newer themes of Android (above API 21). In addition to all the answers above , you can put your theme in styles.xml(v21).
More info here https://developer.android.com/training/material/compatibility.html
Not sure if you really want to set it programmatically, but you might try this: How to setTheme to an activity at runtime? It doesn't work call setTheme before onCreate and setContentView
If you're looking to set it for the whole application, it might be easier/cleaner to set it in the AndroidManifest.xml file instead.
<application android:theme="#style/CustomTheme">
Also, I'd highly avoid using a style name that has the values in it. The point of using a style is to avoid hard coding the values and allowing them to be configurable and reusable. What if you want to change the colorPrimary, are you also going to change your style name?
To set theme at runtime you can use following line of code :
setTheme(android.R.style.Theme_Name);
and write it before calling setContentView() and super.onCreate() method inside onCreate() method.
If you want to change that kind of stuff during runtime, you must insert all those "setTheme(android.R.style.Theme_Name);" methods inside runonUiThread, like this:
public class BasicActivity extends AppCompatActivity {
public static String MY_PREFS = "MY_PREFS";
int prefMode = Activity.MODE_PRIVATE;
protected void onCreate(Bundle savedInstanceState) {
JsonParser parser = new JsonParser(getApplicationContext());
int resourceId = this.getResources().getIdentifier(parser.getThemeID(), "style", this.getPackageName());
runOnUiThread(new Runnable() {
#Override
public void run() {
setTheme(R.style.c_2ecc71_BC6C2B);
}
});
recreate();
if (android.os.Build.VERSION.SDK_INT >= 19) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
super.onCreate(savedInstanceState);
}
}
and call recreate() after!
According to Android -
void recreate ()
Cause this Activity to be recreated with a new instance. This results in essentially the same flow as when the Activity is created due to a configuration change -- the current instance will go through its lifecycle to onDestroy() and a new instance then created after it.
Just modify your BasicActivity and MainActivity as shown in below and create appropriate theme. You can use shared preference for checking theme state during app up.
BasicActivity .java
public abstract class BasicActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
if (getLayoutID() != 0) {
setContentView(getLayoutID());
}
} catch (Exception ex) { /* ... */ }
final boolean THEME_DARK = true;// read appropriate value from SP or any other storage
Toolbar toolbar;
if ((toolbar = getToolbar()) != null) {
if (THEME_DARK/* check theme type here*/) {
toolbar.setPopupTheme(R.style.c_2ecc71_BC6C2B);
}
try {
setSupportActionBar(toolbar);
} catch (NoClassDefFoundError e) {
// Toast
finish();
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.setStatusBarColor(getResources().getColor(R.color.colorPrimary));
}
}
public abstract Toolbar getToolbar();
public abstract int getLayoutID();
}
MainActivity.java
public class MainActivity extends BasicActivity {
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public Toolbar getToolbar() {
return toolbar == null ? toolbar = (Toolbar) findViewById(R.id.toolbar) : toolbar;
}
#Override
public int getLayoutID() {
return R.layout.activity_main;
}
}
You have hard-coded the theme in BaseActivity , rather than getting targetted resource id.
You need to put setTheme(value_from_resourceId);
Currently the BaseActivity always calls irrespective of value that you parsed
setTheme(R.style.c_2ecc71_BC6C2B);
than referring the runtime value

Confused on Reading SharedPreferences Without a PreferenceActivity

Because I want an AppCompat Action Bar on all of my settings submenus, I had to implement a workaround and my Settings Activity extends AppCompatActivity, not PreferenceActivity. I'm using a PreferenceFragment in the activity to handle the preferences, and each PreferenceScreen has its own xml file, which the PreferenceFragment switches out for each submenu in the settings. All of this was necessary to get the Action Bar to stay put through all of my submenus.
I'm trying to read a string value from the shared preferences file from within my MainActivity, and I've tried three different methods for getting that information, none of which have worked:
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String btSelectPref = sharedPref.getString(getString(R.string.bt_select_key), "");
,
SharedPreferences sharedPref = getSharedPreferences(name, MODE_PRIVATE);
String btSelectPref = sharedPref.getString(getString(R.string.bt_select_key), "");
and
SharedPreferences sharedPref = getPreferences(MODE_PRIVATE);
String btSelectPref = sharedPref.getString(getString(R.string.bt_select_key), "");
Here is the relevant section of my preferences.xml:
<PreferenceCategory
android:title="Bluetooth"
android:key="pref_bt">
<Preference
android:title="Select Bluetooth Device"
android:key="#string/bt_select_key"
android:defaultValue="0">
</Preference>
</PreferenceCategory>
This should fill the btSelectPref string with a "0", but it's always empty when I test it. I have included PreferenceManager.setDefaultValues(this, R.xml.preferences, false); in onCreate in my MainActivity, so the default values should be set.
I'm not sure which of these methods I should be using since I have multiple resource files for my settings, but none of them seem to be working for me. In the case of getSharedPreferences(name, MODE_PRIVATE), I have no idea what the name parameter should be referencing, since I've never named my shared preferences file.
EDIT: It turns out my issue was not related to getting values from the shared preferences file. I just had the wrong xml tag on the preference I was trying to check the value of. I changed it from a generic <Preference> tag to a <ListPreference> and my code started working with PreferenceManager.getDefaultSharedPreferences().
What you want to do and what you are doing differs. If you just want to put default shared preference for a key then consider this example. If your whole activity has just one shared pref file then you need not specify any name. It will automatically get it.
public MainActivity extends AppCompatActivity {
SharedPreferences mPrefs;
int test;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_counter);
mPrefs = this.getPreferences(Context.MODE_PRIVATE);
test = mPrefs.getInt("pref_bt_select", 0);}
}
For the above example you can define the key and default value in your strings.xml and then you can refer to it while looking for the prefs you want.
Hey I have used AppCompat for my preference screen too.I did this because I wanted to use Vintage Chroma and this was the only way. But I am able to use PreferenceManager.getDefaultSharedPreference() without any errors.
Also if you want to use default shared preferences in the Fragment you can use :
SharedPreferences preferences = this.getActivity().getSharedPreferences("pref", Context.MODE_PRIVATE);
Here is my full code :
public class PreferencesActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager()
.beginTransaction()
.replace(android.R.id.content, new PreferencesScreen())
.commit();
ActionBar toolbar = getSupportActionBar();
if (toolbar != null) {
toolbar.setDisplayHomeAsUpEnabled(true);
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
public static class PreferencesScreen extends PreferenceFragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings_xml);
}
}
}
Here is my code snippet for MAinActivity
Just the initial part where I set the default text theme.
`public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
AutoCompleteTextView mytextview;
public static String[] list;
ArrayList<String> recent = new ArrayList<String>();
public int recent_index = 0;
Menu mMenu;
#Override
protected void onCreate(Bundle savedInstanceState) {
/*Setting default theme.*/
SharedPreferences Sp= PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
int firstRun=Sp.getInt("firstRun",0);
if(firstRun==0)
{
SharedPreferences.Editor editor=Sp.edit();
editor.putInt("paragraphFontColor", Color.parseColor("#ffffff"));
editor.putInt("headingFontColor",Color.parseColor("#DE5246"));
editor.putInt("subheadingFontColor",Color.parseColor("#597d5e"));
editor.putInt("hyperlinksFontColor",Color.parseColor("#A5D8F5"));
editor.putInt("bodyColor",Color.parseColor("#2b2b2b"));
editor.putString("paragraphFont","PrintClearly.otf");
editor.putString("headingFont","PrintBold.otf");
editor.putString("subheadingFont","PrintBold.otf");
editor.putString("hyperlinkFont","PrintBold.otf");
editor.putString("paragraphFontStyle","normal");
editor.putString("headingFontStyle","normal");
editor.putString("subheadingFontStyle","normal");
editor.putString("hyperlinkFontStyle","normal");
editor.putString("actionBarColor","#597d5e");
editor.putString("paragraphFontSize","20px");
editor.putString("headingFontSize","30px");
editor.putString("subheadingFontSize","20px");
editor.putString("hyperlinkFontSize","20px");
editor.putString("firstRun",0);
editor.commit();
}
`

How to change current Theme at runtime in Android [duplicate]

This question already has answers here:
Implementing user choice of theme
(4 answers)
Closed 5 years ago.
I've created a PreferenceActivity that allows the user to choose the theme he wants to apply to the entire application.
When the user selects a theme, this code is executed:
if (...) {
getApplication().setTheme(R.style.BlackTheme);
} else {
getApplication().setTheme(R.style.LightTheme);
}
But, even though I've checked with the debugger that the code is being executed, I can't see any change in the user interface.
Themes are defined in res/values/styles.xml, and Eclipse does not show any error.
<resources>
<style name="LightTheme" parent="#android:style/Theme.Light">
</style>
<style name="BlackTheme" parent="#android:style/Theme.Black">
</style>
</resources>
Any idea about what could be happening and how to fix it?
Should I call setTheme at any special point in the code? My application consists of several Activities if that helps.
I would like to see the method too, where you set once for all your activities. But as far I know you have to set in each activity before showing any views.
For reference check this:
http://www.anddev.org/applying_a_theme_to_your_application-t817.html
Edit (copied from that forum):
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Call setTheme before creation of any(!) View.
setTheme(android.R.style.Theme_Dark);
// ...
setContentView(R.layout.main);
}
Edit
If you call setTheme after super.onCreate(savedInstanceState); your activity recreated but if you call setTheme before super.onCreate(savedInstanceState); your theme will set and activity
does not recreate anymore
protected void onCreate(Bundle savedInstanceState) {
setTheme(android.R.style.Theme_Dark);
super.onCreate(savedInstanceState);
// ...
setContentView(R.layout.main);
}
If you want to change theme of an already existing activity, call recreate() after setTheme().
Note: don't call recreate if you change theme in onCreate(), to avoid infinite loop.
recreate() (as mentioned by TPReal) will only restart current activity, but the previous activities will still be in back stack and theme will not be applied to them.
So, another solution for this problem is to recreate the task stack completely, like this:
TaskStackBuilder.create(getActivity())
.addNextIntent(new Intent(getActivity(), MainActivity.class))
.addNextIntent(getActivity().getIntent())
.startActivities();
EDIT:
Just put the code above after you perform changing of theme on the UI or somewhere else. All your activities should have method setTheme() called before onCreate(), probably in some parent activity. It is also a normal approach to store the theme chosen in SharedPreferences, read it and then set using setTheme() method.
i got the same problem but i found the solution.
public class EditTextSmartPhoneActivity extends Activity implements DialogInterface.OnClickListener
{
public final static int CREATE_DIALOG = -1;
public final static int THEME_HOLO_LIGHT = 0;
public final static int THEME_BLACK = 1;
int position;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
position = getIntent().getIntExtra("position", -1);
switch(position)
{
case CREATE_DIALOG:
createDialog();
break;
case THEME_HOLO_LIGHT:
setTheme(android.R.style.Theme_Holo_Light);
break;
case THEME_BLACK:
setTheme(android.R.style.Theme_Black);
break;
default:
}
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
private void createDialog()
{
/** Options for user to select*/
String choose[] = {"Theme_Holo_Light","Theme_Black"};
AlertDialog.Builder b = new AlertDialog.Builder(this);
/** Setting a title for the window */
b.setTitle("Choose your Application Theme");
/** Setting items to the alert dialog */
b.setSingleChoiceItems(choose, 0, null);
/** Setting a positive button and its listener */
b.setPositiveButton("OK",this);
/** Setting a positive button and its listener */
b.setNegativeButton("Cancel", null);
/** Creating the alert dialog window using the builder class */
AlertDialog d = b.create();
/** show dialog*/
d.show();
}
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
AlertDialog alert = (AlertDialog)dialog;
int position = alert.getListView().getCheckedItemPosition();
finish();
Intent intent = new Intent(this, EditTextSmartPhoneActivity.class);
intent.putExtra("position", position);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
We have to set theme before calling 'super.onCreate()' and 'setContentView()' method.
Check out this link for applying new theme to whole application at runtime.
I had a similar problem and I solved in this way..
#Override
public void onCreate(Bundle savedInstanceState) {
if (getIntent().hasExtra("bundle") && savedInstanceState==null){
savedInstanceState = getIntent().getExtras().getBundle("bundle");
}
//add code for theme
switch(theme)
{
case LIGHT:
setTheme(R.style.LightTheme);
break;
case BLACK:
setTheme(R.style.BlackTheme);
break;
default:
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//code
}
this code is for recreate the Activity saving Bundle and changing the theme. You have to write your own onSaveInstanceState(Bundle outState); From API-11 you can use the method recreate() instead
Bundle temp_bundle = new Bundle();
onSaveInstanceState(temp_bundle);
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("bundle", temp_bundle);
startActivity(intent);
finish();
Instead of
getApplication().setTheme(R.style.BlackTheme);
use
setTheme(R.style.BlackTheme);
My code: in onCreate() method:
super.onCreate(savedInstanceState);
if(someExpression) {
setTheme(R.style.OneTheme);
} else {
setTheme(R.style.AnotherTheme);
}
setContentView(R.layout.activity_some_layout);
Somewhere (for example, on a button click):
YourActivity.this.recreate();
You have to recreate activity, otherwise - change won't happen
This is what i have created for Material Design. May it will helpful you.
Have a look for MultipleThemeMaterialDesign
I know that i am late but i would like to post a solution here:
Check the full source code here.
This is the code i used when changing theme using preferences..
SharedPreferences pref = PreferenceManager
.getDefaultSharedPreferences(this);
String themeName = pref.getString("prefSyncFrequency3", "Theme1");
if (themeName.equals("Africa")) {
setTheme(R.style.AppTheme);
} else if (themeName.equals("Colorful Beach")) {
//Toast.makeText(this, "set theme", Toast.LENGTH_SHORT).show();
setTheme(R.style.beach);
} else if (themeName.equals("Abstract")) {
//Toast.makeText(this, "set theme", Toast.LENGTH_SHORT).show();
setTheme(R.style.abstract2);
} else if (themeName.equals("Default")) {
setTheme(R.style.defaulttheme);
}
This way work for me:
#Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(GApplication.getInstance().getTheme());
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
Then you want to change a new theme:
GApplication.getInstance().setTheme(R.style.LightTheme);
recreate();
You can finish the Acivity and recreate it afterwards in this way your activity will be created again and all the views will be created with the new theme.
Call SetContentView(Resource.Layout.Main) after setTheme().
This had no effect for me:
public void changeTheme(int newTheme) {
setTheme(newTheme);
recreate();
}
But this worked:
int theme = R.style.default;
protected void onCreate(Bundle savedInstanceState) {
setTheme(this.theme);
super.onCreate(savedInstanceState);
}
public void changeTheme(int newTheme) {
this.theme = newTheme;
recreate();
}

Categories

Resources