如何切换主题(夜间模式)而不重新启动活动?

时间:2015-05-11 17:33:01

标签: android android-theme

我制作了一些支持多个主题的应用,但是当用户切换主题时我总是不得不重启应用,因为setTheme()需要在setContentView()之前调用。

我没关系,直到我发现这个应用程序。它可以在两个主题之间无缝切换,也可以使用过渡/动画切换!

enter image description here

请给我一些关于如何实施(以及动画)的提示。谢谢!

4 个答案:

答案 0 :(得分:34)

@Alexander Hanssen的回答基本上已经回答了这个...... 不知道为什么它不被接受...也许是因为finish()/ startActivity()。 我投了赞成票,我试着评论但不能......

无论如何,我会完全按照他描述的风格来做。

const volatile T&

但不是以新意图完成/开始:

<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>

我愿意:

Intent intent = new Intent(this, <yourclass>.class);
startActivity(intent);
finish();

效果如视频所示......

答案 1 :(得分:10)

当您重新启动活动时,转换/动画会使主题更改无缝,这可以通过添加项目来完成&#34; android:windowanimationStyle&#34;对于您的主题,然后引用一种样式,您可以在其中指定Activity在进入和退出时应如何设置动画。 请注意,这使得动画适用于具有该主题的所有活动。

<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>

然后,当您想要更改主题时,可以在单击按钮时执行此操作:

AppSettings settings = AppSettings.getInstance(this);
settings.set(AppSettings.Key.USE_DARK_THEME,
!settings.getBoolean(AppSettings.Key.USE_DARK_THEME));
Intent intent = new Intent(this, <yourclass>.class);
startActivity(intent);
finish();

然后在onCreate方法中,使用setTheme()应用当前在AppSettings中设置的主题,如下所示:

AppSettings settings = AppSettings.getInstance(this);
setTheme(settings.getBoolean(AppSettings.Key.USE_DARK_THEME) ? R.style.AppThemeDark : R.style.AppThemeLight);
super.onCreate(savedInstanceState);
setContentView(<yourlayouthere>);

查看此要点以供参考:https://gist.github.com/alphamu/f2469c28e17b24114fe5

答案 2 :(得分:1)

没有任何东西阻止您再次呼叫setTheme()然后setContentView()。您只需稍微重新构建您的应用程序,以便在更改主题时,您需要重新初始化您可能拥有的对View个对象的引用的任何成员变量。

答案 3 :(得分:0)

对于那些试图为 android 版本 10 或更新寻找解决方案的人。

设置暗/亮模式使用这个:

AppCompatDelegate.setDefaultNightMode(state) //state can be AppCompatDelegate.MODE_NIGHT_YES or AppCompatDelegate.MODE_NIGHT_NO

它会改变你的应用程序的显示,但会闪烁

为了避免活动娱乐闪烁(为了平滑过渡),在您的活动中添加以下方法

@Override
    public void recreate() {
        finish();
        overridePendingTransition(R.anim.anime_fade_in,
                                  R.anim.anime_fade_out);
        startActivity(getIntent());
        overridePendingTransition(R.anim.anime_fade_in,
                                  R.anim.anime_fade_out);
    }