我正在尝试以编程方式更改colorPrimary
和colorAccent
,但我找不到与它们相关的任何方法,例如setThemeColorPrimary(int color)
。我发现的唯一方法是通过Java反射来更改它。但是,我找不到要反映colorPrimary
和colorAccent
字段。
那么,如何以编程方式更改colorPrimary
和colorAccent
呢?
提前谢谢。
据我所知,这是不可能的,你无法访问colorAccent和colorPrimary 字段,这不是Android资源编译过程的工作方式。
没有 主题.颜色原 ,要访问主题属性,您需要使用obtainStyledAtributtes()
或类似的技术。
我知道以编程方式执行此操作的唯一方法是使用setTheme()
方法或使用ContextThemeWrapper()
。这两种方式都需要在 XML 中具有多个样式声明。
覆盖主题属性!
1)如果您不想手动更新每个视图,请继续阅读。
2)如果预定义的原色和强调色集适合您,请继续阅读。
有几个预定义的主题叠加层,并指定了原色和强调色:
<style "ThemeOverlay.MyApp.Red" parent="">
<item name="colorPrimary">#ff0000</item>
<item name="colorPrimaryDark">#880000</item>
<item name="colorAccent">#00ffff</item>
</style>
<style "ThemeOverlay.MyApp.Blue" parent="">
<item name="colorPrimary">#0000ff</item>
<item name="colorPrimaryDark">#000088</item>
<item name="colorAccent">#ffff00</item>
</style>
<!-- Green, orange, etc. -->
现在,您可以包装任何上下文并仅覆盖这三个属性
Context newContext = new ContextThemeWrapper(context, R.style.ThemeOverlay_MyApp_*);
这对于膨胀视图或手动创建视图来说已经足够了。
如何使其自动用于您的所有活动?创建一个所有活动都将扩展的BaseActivity
。此活动将更新其主题,如下所示:
@Override
public void onCreate(Bundle icicle) {
final SharedPreferences prefs = ...;
final String themeColor = prefs.getString("themeColor", ""); // Non-null!
final int themeResId;
switch (themeColor) {
"BLUE":
themeResId = R.style.ThemeOverlay_MyApp_Blue;
default:
themeResId = R.style.ThemeOverlay_MyApp_Red;
}
setTheme(themeResId);
super.onCreate(icicle);
// etc.
}
其中themeResId
是上面定义的主题叠加层之一的资源 ID。我假设颜色主题是应用程序中的用户首选项,并且您存储了一个字符串,例如"RED"
或"BLUE"
,您可以在运行时将其转换为主题资源 ID。不要将资源 ID 存储到首选项中,ID 会因构建而异。