如何在 Android 运行时更改当前主题
我创建了一个 PreferenceActivity,允许用户选择他想要应用于整个应用程序的主题。
当用户选择主题时,将执行以下代码:
if (...) {
getApplication().setTheme(R.style.BlackTheme);
} else {
getApplication().setTheme(R.style.LightTheme);
}
但是,即使我已经使用调试器检查了代码是否正在执行,我在用户界面中看不到任何变化。
主题在 res/values/styles.xml
中定义,Eclipse 不会显示任何错误。
<resources>
<style name="LightTheme" parent="@android:style/Theme.Light">
</style>
<style name="BlackTheme" parent="@android:style/Theme.Black">
</style>
</resources>
知道可能发生什么以及如何解决它吗?
我应该在代码中的任何特殊点调用 setTheme
吗?如果有帮助的话,我的应用程序由多个活动组成。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
我也想看看你为所有活动设置一次的方法。但据我所知,您必须在显示任何视图之前设置每个活动。
作为参考,请检查以下内容:
http://www.anddev.org/applying_a_theme_to_your_application-t817.html
编辑(从该论坛复制):
编辑
如果您在
super.onCreate(savedInstanceState);
之后调用setTheme
,您的 Activity 会重新创建,但如果您在super.onCreate(savedInstanceState) 之前调用
您的主题和活动将设置setTheme
);不再重新创建
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):
Edit
If you call
setTheme
aftersuper.onCreate(savedInstanceState);
your activity recreated but if you callsetTheme
beforesuper.onCreate(savedInstanceState);
your theme will set and activitydoes not recreate anymore
如果您想更改现有活动的主题,请调用
< 之后 >recreate()
代码>setTheme()。注意:如果在
onCreate()
中更改主题,请勿调用recreate,以避免无限循环。If you want to change theme of an already existing activity, call
recreate()
aftersetTheme()
.Note: don't call recreate if you change theme in
onCreate()
, to avoid infinite loop.recreate()
(如TPReal所述)只会重新启动当前活动,但以前的活动仍将在后台堆栈中,主题将不会应用于它们。因此,此问题的另一个解决方案是完全重新创建任务堆栈,如下所示:
编辑:
在 UI 或其他地方执行主题更改后,只需将上面的代码放在上面即可。您的所有活动都应该在
onCreate()
之前调用方法setTheme()
,可能是在某些父活动中。这也是一种正常的方法,将选择的主题存储在 SharedPreferences 中,读取它,然后使用 setTheme() 方法进行设置。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:
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 beforeonCreate()
, probably in some parent activity. It is also a normal approach to store the theme chosen inSharedPreferences
, read it and then set usingsetTheme()
method.我遇到了同样的问题,但我找到了解决方案。
i got the same problem but i found the solution.
我们必须在调用 'super.onCreate()' 和 'setContentView()' 方法之前设置主题。
查看此链接< /a> 用于在运行时将新主题应用于整个应用程序。
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.
我有一个类似的问题,我用这种方式解决了。
这段代码用于重新创建活动保存包并更改主题。您必须编写自己的 onSaveInstanceState(Bundle outState);从 API-11 开始,您可以使用方法 recreate() 代替
I had a similar problem and I solved in this way..
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
而不是
使用
我的代码:在 onCreate() 方法中:
某处(例如,单击按钮时):
您必须重新创建活动,否则 - 更改不会发生
Instead of
use
My code: in onCreate() method:
Somewhere (for example, on a button click):
You have to recreate activity, otherwise - change won't happen
这是我为材料设计创建的。愿它会对你有所帮助。
看看 MultipleThemeMaterialDesign
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..
这种方式对我有用:
然后你想更改一个新主题:
This way work for me:
Then you want to change a new theme:
您可以完成活动并随后重新创建它,这样您的活动将再次创建,并且所有视图都将使用新主题创建。
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.
在 setTheme() 之后调用 SetContentView(Resource.Layout.Main)。
Call SetContentView(Resource.Layout.Main) after setTheme().
这对我没有影响:
但这有效:
This had no effect for me:
But this worked: