有许多关于通过XML创建或自定义Android主题样式的文档和教程,但未能找到在代码中创建它的方法。关于如何在代码而不是xml中创建样式的任何想法?
这是示例XML,需要在代码中以编程方式创建:
<resources>
<style name="AppTheme" parent="android:Theme.Material">
<item name="android:colorPrimary">@color/primary</item>
<item name="android:colorPrimaryDark">@color/primary_dark</item>
<item name="android:colorAccent">@color/accent</item>
</style>
</resources>
答案 0 :(得分:3)
简短回答:以编程方式不可能
创造一个主题&amp;设置为应用程序主题(即使我们实现了创建Theme
对象)没有主题资源ID。
详细信息:
当您致电setTheme
时,该功能会影响ContextWrapper
的方法,
最后用资源id指针调用AssetManager
,AssetManager
类保存应用程序主题的方法,即JNI调用
native static final void applyThemeStyle(long theme, int res, boolean force);
如上所述,我们只能传递资源ID来应用themestyle。但可能的选择是
Window
类特征常量。我们可以用
setFeatureDrawable&amp;用于设置一些drawable的特征常量
比如FEATURE_ACTION_BAR
,FEATURE_CONTEXT_MENU
等.. AjaySharma
&amp;的评论中提到的问题。 Nathan
答案 1 :(得分:2)
TL; DR:不,您不能。这就是Android的工作方式,而且永远不会改变。
有一个简单明了的原因,使得无法以编程方式创建Android主题。也就是说,启动应用程序时,Android将创建一个虚拟窗口,其中显示了应用程序的android:windowBackground
。此时,应用程序进程仍在初始化,并且当应用程序执行开始并返回所启动活动的Activity.onCreate
方法时,虚拟窗口将替换为显示该活动的应用程序窗口。
因此,事实是,由于android:windowBackground
是由主题设置的,但是Android甚至必须在应用启动之前就访问它,因此主题必须是资源,以便可以从以下任何进程(包括系统进程)访问它们:课程。)
此外,主题是资源,因此它们是完全不变的。这就是Android的工作方式。它不能只是突然改变,而且很可能永远不会改变。资源永远无法动态修改的另一个原因是直接的暗示,即APK本身也需要修改-这也不是APK的意思。
有人可能会争辩说“一切都必须以编程的方式在后台进行。”好吧,这是正确的。但是,android.content.res.Resources.Theme
类之所以是最终类是有原因的,这是为了确保什么都不会被覆盖,因此可以保证其行为能够反映资源的内容,这对于系统进程访问{{1}活动主题的}与应用程序启动后的行为方式保持一致。对于android:windowBackground
方法也是如此,这也是最终的方法。确实,如果应用程序可以覆盖该方法,它将能够返回与资源不匹配的值,这是一个问题,因为只有当应用程序启动后,原始的真实android.content.Context.obtainStyledResources
才会发生已经显示。