In my android app, I set the theme like this:
#Override
public void onCreate(Bundle savedInstanceState){
ThemeSetterActivity.setStyle(Main_MenuActivity.this); // this just calls context.setTheme();
super.onCreate(savedInstanceState);
setContentView(R.layout.main_menu);
}
But how do I change the theme using
ThemeSetterActivity.setStyle(Main_MenuActivity.this);
when it's in the onresume event. When I try it, it does call the function but the theme doesn't change. Does it have something to do with not calling:
super.onCreate(savedInstanceState);
setContentView(R.layout.main_menu);
To change the theme of your application during run time, you can use the setTheme(...) method within the activity. You must set the theme to an activity, before loading the views of that activity.
For more info and implementation, refer the link:
Updated
And, as per the docs to set theme you need to restart the entire activity.
You can try this code in onResume() of your activity,
Intent i = getIntent();
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
Related
I provide theme option for my app user. But I found the theme will reset back to default theme after rotation.
Here is my code:
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
config = PreferenceManager.getDefaultSharedPreferences(this);
theme = config.getString("theme", "");
setActionBarTheme(theme);
setContentView(R.layout.main);
}
private void setActionBarTheme(String theme)
{
if(theme.equals("Holo Red"))
{
setTheme(R.style.onTime_Theme_Holo_Red);
}else
{
setTheme(R.style.onTime_Theme_Default);
}
}
This activity is hosting fragments, when device is rotated, fragment remain but theme reset.
If device config changed, it should recreate the activity. Is it bug or I miss something?
As #CBergson pointed out, you can save the theme and recreate it whe the Activity is recreated.
On the other hand you can prevent Android from destroying your Activity by adding the following line to your AndroidManifest.xml:
<activity android:name="YourActivity"
android:configChanges="orientation|screenSize" />
Further reading here.
You should save/update the current theme in your preferences, so that It wont be the default value. Activity life-cycle will repeat itself (stop-destroy-start etc...) when the rotation happens. You need to save it before the cycle is completed before the next activity cycle starts.
Could someone tell me how i can switch the the theme from holo to holo light in my application on runtime ?
I would like to have two buttons in settings to choose light or black theme.
How can it be set applicationwide and not only for the activity ?
I already tried a few things with setTheme() but i wasn't able to change the theme when i click a button.
This is my Settings activity where i would like to set the theme:
public class SettingsActivity extends Activity {
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(android.R.style.Theme_Holo_Light);
super.onCreate(savedInstanceState);
setContentView(R.layout.settings);
}
well this works and my Theme is set but as i am saying i would like to change it systemwide by pressing a button.
Thanks !
As you can see theme is setting on the onCreate() and before setContentView(). So you should call the oncreate() method again when you want to change the theme. But the onCreate() function will be called only once in the life cycle of an Activity.
There is a simple way to do this. I am not sure that it is the best way.
Suppose you want to apply new theme to Activity 1 on a button click.
inside the onClick event
Save the theme to be applied such that it should be retained even after the application restart (preferences or static volatile variables can be used).
Finish the current activity (Activity 1) and call a new activity (Activity 2).
Now in Activity 2
Call Activity 1 and finish current activity (Activity 2).
In Activity 1
Apply the saved theme inside onCreate.
Hope it is not confusing.. :)
You cannot change the theme of other applications (thank goodness).
The only way to somewhat accomplish this would be to create your own build of the operating system with your own theme as the device default theme. However, applications that do not use the device default theme (i.e. they explicitly set the theme to Holo, Holo light, etc) will not get the device default theme.
Edit- To accomplish this application-wide using a base Activity, create an Activity that looks like this:
public class BaseActivity extends Activity {
private static final int DEFAULT_THEME_ID = R.id.my_default_theme;
#Override
public void onCreate(Bundle savedInstanceState) {
int themeId = PreferenceManager.getDefaultSharedPreferences(context)
.getInt("themeId", DEFAULT_THEME_ID);
setTheme(themeId);
super.onCreate(savedInstanceState);
}
}
Then all of your Activities should extend this BaseActivity. When you want to change the theme, be sure to save it to your SharedPreferences.
this code runs after startActivity, but setting it after:
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
keep old (default) android animation. Why?
Because by the time your activity starts and has a chance to overridePendingTransition, the transition has already taken place. You should change the window transitions in a Theme, and set the Activity theme at the manifest.
I have searched but cant find a solution to my problem.
What I need to do is set a random theme and then have all other views adopt this theme. The randomising of the theme isn't the problem, I know it's woking. Whats the issue is refreshing the views already in the stack.
I call
int theme = Constants.THEMES[randomInt];
setTheme(theme);
in an activity somewhere in the stack and then call invalidate() on that activity. Nothing happens in that activity but when I go to other activities the new theme applies.
Also when I go 'back' to my mainActivity I can't figure out how to get the View to redraw.
I'm calling
#Override
protected void onResume() {
super.onResume();
if(refreshNeeded){
getWindow().getDecorView().findViewById(
android.R.id.content).getRootView().invalidate();
}
}
but nothing again. I cant figure out how to get it to redraw with the new theme.
Am I missing something obvious?
Call this at Button click
getApplication().setTheme(R.style.Theme_Black);
setTheme(R.style.Theme_Black);
Intent n = new Intent(activityA.this , activityB.class);
startactivity(n);
It will work. But you must have all widget styles in your themes.xml in values folder
Call setTheme(R.style.Theme) before super.onCreate and setContentView.
So I have my main activity that has some views and I have an activity that has the preferences.
I want to, when the activity of the preferences is destroyed, to recreate my main activity, because some views depend on the preferences.
I don't see a way to do this.
Thanks.
Check what's changed in onResume() of your main Activity. Then, based on whatever your logic is, set the contentView to the appropriate Views or manipulate whatever Views you need to.
for me I always make all work in separated method and call it in onCreate()..
i.e:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//here call method contains views initializing, logic, etc..
initializingPro();
}
private void initializingPro(){
//....
webview=(WebView)findById(R.id.webb);
//....
}
now in you case you want to recreate those components, just call this method again initializingPro() ,, no need to destroy activity..
good luck,