以编程方式切换应用程序的整体主题?

43

我正在尝试获取用户选择的主题,但感觉离成功很近。在AndroidManifest.xml中定义主题可以正常工作,但(据我所知)无法根据应用程序首选项更改:

<application 
    android:theme="@style/theme_sunshine" 
    android:icon="@drawable/icon" 
    android:label="@string/app_name">

或者在每个活动中动态设置它也可以:

someChosenTheme = PreferenceManager.getDefaultSharedPreferences(this).getString("themePreference", "theme_twilight");
setTheme(someOtherChosenTheme);

但是这看起来很混乱,我更愿意在一个地方为整个应用程序设置主题。我的第一个想法是一旦我的主活动启动就立即获取应用程序上下文并在那里进行操作:

getApplicationContext().setTheme(R.style.theme_dummy);
据我所知,这个方法应该可以解决问题,但实际上它并没有起到作用 - 整个应用程序仍使用默认的Android样式。 如果以上方法是有效的,那么我可能还做了其他愚蠢的事情吗?
如果有所帮助,请给我一些指引!我在API级别3中进行开发。
相关问题请参考这里
2个回答

33

这基本上就是我正在做的事情。虽然没有多重继承,例如自定义ListActivity,但仍不是理想的,但不便之处很小。非常有帮助的教程,尽管我已经读过它 :) - Cheezmeister
实际上,我在每个应用程序中都有一个BaseListActivity和一个Base(Generic)Activity。 BaseListActivity内置了CRUD(读取、添加、编辑、删除)的常见处理方式,因此创建新的列表活动并覆盖一些方法非常容易。当然,如果我添加MapActivity或TabActivity,我也必须为它们创建BaseXActivity。有时候多重继承就是更好的选择 :) - peter3
6
在每个活动的“setContentView”被调用前加入“setTheme”,这样做确实是正确的解决方案吗?没有一种单一系统范围内的解决方案吗?而且,所有已经在运行的活动会发生什么? - android developer
1
对于活动状态,只需在主题更改时调用recreate()。闪烁很丑,但我们必须忍受它。 - user2154462
一个很棒的教程链接,帮助我回答了最近得到的一个无关问题:“像?actionBarSize这样的属性在哪里定义,以及它们是如何工作的” :) - Ralphilius
该链接有效,但其内部的源代码却无法正常工作,因为它会出现 Dropbox 错误。因此,主要问题在文章中没有得到回答,即如何以编程方式更改主题。 - samman

5

可能有一个好的解决方案,但我找不到,所以最终在一个帮助类中创建了一个小的静态帮助方法,该方法接受一个Activity并基本上执行你写的那两行代码。当然,它不是完美的,但只需要在我的应用程序的每个onCreate()方法中添加一行短代码就可以容忍。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接