通过反射改变colorPrimary和colorAccent

时间:2016-03-09 13:49:47

标签: java android reflection android-theme

我正在尝试以编程方式更改colorPrimarycolorAccent,但我找不到与它们相关的任何方法,例如setThemeColorPrimary(int color)。我发现的唯一方法是通过Java reflection进行更改。但是,我找不到要反映的colorPrimarycolorAccent字段。

那么,如何以编程方式更改colorPrimarycolorAccent

提前致谢。

2 个答案:

答案 0 :(得分:1)

据我所知,如果不可能,您无法访问colorAccent和colorPrimary字段,而这些字段并非Android资源编译过程的工作方式。

没有Theme.colorPrimary这样的东西,要访问你需要使用obtainStyledAtributtes()或类似技术的主题属性。

我知道以编程方式执行此操作的唯一方法是使用setTheme()方法或使用ContextThemeWrapper()。这两种方式都需要您在XML中使用多个样式声明。

答案 1 :(得分:0)

无法覆盖主题属性!

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会在不同版本中更改。