Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save alphamu/f2469c28e17b24114fe5 to your computer and use it in GitHub Desktop.
Save alphamu/f2469c28e17b24114fe5 to your computer and use it in GitHub Desktop.
Example of how to change themes at runtime with a smooth animation. In this example, we just switch between a light and a dark theme. The activity animation is defined in the theme and as such will be default on all activities with the set theme. [Demo Video here](http://youtu.be/Ps0phswbHls).
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
public class TransitionThemeActivity extends AppCompatActivity implements View.OnClickListener {
ListView mListView;
Button mChangeTheme;
@Override
protected void onCreate(Bundle savedInstanceState) {
AppSettings settings = AppSettings.getInstance(this);
setTheme(settings.getBoolean(AppSettings.Key.USE_DARK_THEME) ? R.style.AppThemeDark : R.style.AppThemeLight);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_transition_theme);
mListView = (ListView) findViewById(R.id.cheese_list);
mListView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, Cheeses.CHEESES));
mChangeTheme = (Button) findViewById(R.id.change_theme);
mChangeTheme.setOnClickListener(this);
}
@Override
public void onClick(View v) {
AppSettings settings = AppSettings.getInstance(this);
settings.set(AppSettings.Key.USE_DARK_THEME,
!settings.getBoolean(AppSettings.Key.USE_DARK_THEME));
Intent intent = new Intent(this, TransitionThemeActivity.class);
startActivity(intent);
finish();
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.alimuzaffar.android.scratchpad" >
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppThemeLight" >
<activity
android:name=".TransitionThemeActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
<resources>
<style name="AppThemeLight" parent="Theme.AppCompat.Light">
<!-- Customize your theme here. -->
<item name="android:windowAnimationStyle">@style/WindowAnimationTransition</item>
</style>
<style name="AppThemeDark" parent="Theme.AppCompat">
<!-- Customize your theme here. -->
<item name="android:windowAnimationStyle">@style/WindowAnimationTransition</item>
</style>
<!-- This will set the fade in animation on all your activities by default -->
<style name="WindowAnimationTransition">
<item name="android:windowEnterAnimation">@android:anim/fade_in</item>
<item name="android:windowExitAnimation">@android:anim/fade_out</item>
</style>
</resources>
@Neha3512
Copy link

Error:(37, 49) error: package AppSettings does not exist
Error:(36, 33) error: package AppSettings does not exist
Error:(35, 32) error: cannot find symbol variable AppSettings
Error:(35, 9) error: cannot find symbol class AppSettings
Error:(28, 50) error: cannot find symbol variable change_theme
Error:(26, 98) error: cannot find symbol variable Cheeses
Error:(25, 49) error: cannot find symbol variable cheese_list
Error:(21, 49) error: package AppSettings does not exist
Error:(20, 32) error: cannot find symbol variable AppSettings
Error:(20, 9) error: cannot find symbol class AppSettings

@shakil807g
Copy link

shakil807g commented Dec 11, 2016

you can also use recreate() method from Activity class Instead of
Intent intent = new Intent(this, TransitionThemeActivity.class);
startActivity(intent);
finish();

@CosimoSguanci
Copy link

What's AppSettings ?

@shoheikawano
Copy link

Thanks for your gist! One thing I noticed is that (assuming AppSettings class is your custom class) instead of having custom AppSettings class you could use AppCompatDelegate class from Android Support Library 23.2.0 to setDefaultNightMode and getDefaultNightMode. https://carthrottle.io/how-to-implement-flexible-night-mode-in-your-android-app-f00f0f83b70e#.p3vwlr68f

@shoheikawano
Copy link

shoheikawano commented Jan 9, 2017

@shakil807g I am guessing the reason for it is because calling recreate() does not trigger window to animate

@drobyshys
Copy link

drobyshys commented Apr 18, 2017

how can I save activity's instanceState without use activity.recreate()?

@junebug12851
Copy link

So essentially the only actual transition part is

<style name="WindowAnimationTransition">
    <item name="android:windowEnterAnimation">@android:anim/fade_in</item>
    <item name="android:windowExitAnimation">@android:anim/fade_out</item>
</style>

and referenced in any theme with

<item name="android:windowAnimationStyle">@style/WindowAnimationTransition</item>

The other unrelated small bit of code is just a general theme switcher but off-topic to the gist title

Intent intent = new Intent(this, TransitionThemeActivity.class);
startActivity(intent);
finish();

all the rest is completely offtopic and unrelated such as settings saving/loading, general manifest settings, and mechanics and design of switching themes.

To help cleanup for those interested and to save them from skimming through all the lines of code and files.

@itisksn
Copy link

itisksn commented Mar 10, 2018

How can i save the instance of activity

@MohammedSaleh59
Copy link

`public class MainActivity extends ActionBarActivity {

protected SharedPreferences mPrefs;

@OverRide
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPrefs = PreferenceManager.getDefaultSharedPreferences(this);

	SharedPreferences.Editor prefEditor = mPrefs.edit();
	prefEditor.putBoolean("USE_DARK_THEME", !mPrefs.getBoolean("USE_DARK_THEME",false));
	prefEditor.commit();
	setTheme(mPrefs.getBoolean("USE_DARK_THEME",false) ? R.style.AppThemeDark : R.style.AppThemeLight);
            setContentView(R.layout.activity_main);

}

styles.xml


<style name="AppThemeLight" parent="Theme.AppCompat.Light"> @style/WindowAnimationTransition </style>
<style name="AppThemeDark" parent="Theme.AppCompat">
    <!-- Customize your theme here. -->
    <item name="android:windowAnimationStyle">@style/WindowAnimationTransition</item>
</style>
<!-- This will set the fade in animation on all your activities by default -->
<style name="WindowAnimationTransition">
    <item name="android:windowEnterAnimation">@android:anim/fade_in</item>
    <item name="android:windowExitAnimation">@android:anim/fade_out</item>
</style> 

`

@j-mendez
Copy link

and to do this with react-native?

@MohammedAbidNafi
Copy link

Thanks for the gist was helpful to implement fade transition in my existing dark/light mode switcher

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment