我做了几个支持多主题的应用程序,但每当用户切换主题时,我总是不得不重新启动应用程序,因为setTheme()
需要在setContentView()
之前调用。
直到我发现了这个应用程序,它可以无缝地在两个主题之间切换,并且带有过渡/动画效果!
请给我一些关于如何实现这个功能(包括动画)的提示。谢谢!
我做了几个支持多主题的应用程序,但每当用户切换主题时,我总是不得不重新启动应用程序,因为setTheme()
需要在setContentView()
之前调用。
直到我发现了这个应用程序,它可以无缝地在两个主题之间切换,并且带有过渡/动画效果!
请给我一些关于如何实现这个功能(包括动画)的提示。谢谢!
@Alexander Hanssen的回答基本上已经回答了这个问题...不知道为什么没有被接受...可能是因为finish()/startActivity()的原因。 我投了票,但我试图发表评论却无法...
无论如何,就样式而言,我会完全按照他所描述的去做。
<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();
我会做:
@Override
protected void onCreate(Bundle savedInstanceState) {
// MUST do this before super call or setContentView(...)
// pick which theme DAY or NIGHT from settings
setTheme(someSettings.get(PREFFERED_THEME) ? R.style.AppThemeLight : R.style.AppThemeDark);
super.onCreate(savedInstanceState);
}
// Somewhere in your activity where the button switches the theme
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// decide which theme to use DAY or NIGHT and save it
someSettings.save(PREFFERED_THEME, isDay());
Activity.this.recreate();
}
});
效果如视频所示...
当您重新启动活动时,转换/动画使主题更改无缝,可以通过将项目"android:windowanimationStyle"添加到您的主题中,并引用一个样式,在其中指定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>);
查看此gist以供参考:https://gist.github.com/alphamu/f2469c28e17b24114fe5
针对那些正在寻找 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);
}
onDestroy()
,然后创建一个新实例。在片段中简单高效的一行代码:
requireActivity().recreate();
针对此次活动:
recreate();
没有任何东西阻止你调用 setTheme()
然后再次调用 setContentView()
。 但是,您需要重新构建您的应用程序,以便如果更改主题,您需要重新初始化可能持有对 View
对象引用的任何成员变量。
以上所有的答案并不能真正防止活动被重新创建! 正确的解决方案应该是这样的:
AndroidManifest.xml
文件的configChanges字段中添加"uiMode",以避免在切换到暗黑模式时重新创建活动。android:configChanges="uiMode"
onConfigureChanged()
函数中,在切换到暗黑模式时手动更新所有的视图颜色。您可以参考这篇文章获取更多详细信息: https://proandroiddev.com/daynight-applying-dark-mode-without-recreating-your-app-c8a62d51092d