在这里搜索了几个小时并测试了这个和那个,我既不能解决我的问题,也没有找到适用于我的问题的任何问题/答案 - 但也许我只使用错误的搜索条件 - 所以我很感激对于正确方向的任何提示!
基本上它是关于使用2个主题(Dark& Light)的应用程序,其中一些TextView显示状态 - 状态可以是On或Off,为了更好地识别状态,文本的颜色应该反映状态:红色表示关闭,绿色表示开启。
当我没有使用任何主题或样式时,我只使用TextView的.setColor(#ffff0000)作为红色,依此类推......
然后我开始利用黑暗/光明主题在不同情况下获得更好的可见性 - 例如户外黑色文字在白色背景上更容易阅读。因此我已经定义了我的2个主题,覆盖了textAppearance:
<style name="Theme.MyApp" parent="Theme.Sherlock">
...
<item name="android:textAppearance">@style/TextNormal</item>
...
</style>
<style name="Theme.MyApp.Light" parent="Theme.Sherlock.Light">
...
<item name="android:textAppearance">@style/TextNormalLight</item>
...
<style name="TextNormal">
<item name="android:textColor">#ffffffff</item>
</style>
<style name="TextNormalLight">
<item name="android:textColor">#ff000000</item>
</style>
此工作正常,“正常”文本视图以正确的颜色显示,具体取决于主题。到目前为止一切都很好!
我没有使用TextView的setColor,而是转而使用.setTextAppearance tv.setTextAppearance(getSherlockActivity(),R.style.TextRed);
并定义了一些样式(只粘贴一个,其他是TextGreen,......):
<style name="TextRed">
<item name="android:textColor">#ffff0000</item>
</style>
这也行得正常!
并最终解决了我的问题:
现在我希望根据主题为“红色”设置不同的颜色......
所以我保留TextRed样式,并添加一个样式用于Light主题,进行测试,我只是做了一个奇怪的颜色,看看它是否正常工作:
<style name="TextRedLight">
<item name="android:textColor">#ffffff00</item>
</style>
如果我在TextView的.setTextAppearance周围放置一个switch语句,并根据所选主题选择正确的样式 - 伪代码:
switch (currentheme) {
case Dark: tv.setTextAppearance(... R.style.TextRed); break;
case Light: tv.setTextAppearance(... R.style.TextRedLight); break;
}
现在的挑战/问题是 - 如何避免切换声明?
当引用layout.xml文件中的样式时,我们可以使用?引用以尊重当前主题......(而不是“@”)
在这种情况下,我需要在运行时设置样式和尊重主题:所以它必须由代码完成,而不是由xml完成 - 但是setTextAppearance只接受id为风格,而不是主题 - 通配符+ id ...
这就是我被卡住的地方...是的,我可以围绕这个包装一个类并将它保持在代码中的一行并“隐藏”此类中的主题检测/开关语句,但另一方面手 - Android的复杂风格/主题架构也应该有解决这个问题的方法,不应该......?
使用主题和样式似乎有点无意义,只要需要helperclasses或switch / if-statements来完成一些增强的东西......
感谢任何提示/想法!!!
编辑1 - 在Tomáš回答之后: 更新了style.xml:
<style name="TextNormal" parent="Theme.ARMoDroid">
<item name="android:textColor">#ffffffff</item>
</style>
<style name="TextNormal" parent="Theme.ARMoDroid.Light">
<item name="android:textColor">#ff000000</item>
</style>
<style name="TextRed" parent="Theme.ARMoDroid">
<item name="android:textColor">#ffff0000</item>
</style>
<style name="TextRed" parent="Theme.ARMoDroid.Light">
<item name="android:textColor">#ffffff00</item>
</style>
在layout.xml中分配TextNormal的TextViews,或者在以下两个主题引用TextNormal时使用:
<item name="android:textAppearance">@style/TextNormal</item>
与以前一样(使用这种不同的方法),当使用红色文本时也是如此。
但最初的问题仍然存在: 当我想(在运行时)将文本的颜色更改为红色时,使用
tv.setTextAppearance(getActivity(),R.style.TextRed)
它总是使用TextRed的最后一个定义 - 所以在上面的定义中,文本将被着色#ffffff00 - &gt;黄色当我交换2个TextRed定义的顺序时,它使用的是最后一个定义 - #ffff0000 - 并且文本是红色的。
因此,在运行时设置样式时,setTextAppearance不是Theme-Aware - 它不区分当前主题和2个定义的样式。
我们可以根据主题定义一个具有不同textcolor值的样式,并根据所选主题正确着色 - 只要它的样式在layout.xml中指定,或者主题集的此样式为默认值
但是在运行时在代码中动态切换样式时,我们仍然需要类似上面的switch语句 - 检测选择了哪个主题,并根据主题,将不同的样式应用于textview。
我想要实现的是,它应该根据当前主题选择正确的“TextRed”样式。所以不需要硬编码主题意识......一旦添加了新的主题,所提到的switch语句也必须更新......
编辑2:我当前的“解决方案”
我想我也可能发布当前的解决方案,但这并不是一个很好的解决方案 - 尽管它有效 - 但它是每种风格的自定义代码,而另一个主题则是更多的代码......
辅助函数如下所示:
public static int getThemedStyle(int normalStyle) {
if (prefs==null) { prefs = PreferenceManager.getDefaultSharedPreferences(appContext); }
int theme = Integer.valueOf(prefs.getString("GUI_Theme","0"));
if (theme==0) return normalStyle; //dark theme
else { //return correct Light-Theme Style
switch (normalStyle) {
case R.style.TextNormal: return R.style.TextNormalLight;
case R.style.TextRed: return R.style.TextRedLight;
case R.style.TextOrange: return R.style.TextOrangeLight;
case R.style.TextGreen: return R.style.TextGreenLight;
case R.style.TextYellow: return R.style.TextYellowLight;
case R.style.TextBlue: return R.style.TextBlueLight;
default: return normalStyle;
} //switch
} //else theme==0
} //getThemedStyle
片段中的我通过在onCreate上调用上面的函数来缓存样式引用:
styleRed = preferences.getThemedStyle(R.style.TextRed);
styleOrange = preferences.getThemedStyle(R.style.TextOrange);
styleGreen = preferences.getThemedStyle(R.style.TextGreen);
最后使用:
分配样式tv.setTextAppearance(getSherlockActivity(), styleRed);
工作,但很复杂,如果这是它的方式,那很难过......;)
答案 0 :(得分:1)
你试过这个吗?
<style name="Theme.MyApp" parent="Theme.Sherlock">
...
</style>
<style name="Theme.MyApp.Light" parent="Theme.Sherlock.Light">
...
</style>
<style name="TextNormal" parent="Theme.MyApp">
<item name="android:textColor">#ffffffff</item>
</style>
<style name="TextNormal" parent="Theme.MyApp.Light">
<item name="android:textColor">#ff000000</item>
</style>
layout.xml中的引用是:
<TextView style="@style/TextNormal" .../>
答案 1 :(得分:0)
回答我自己的问题:
所以代替我的工作 - 切换声明,仍然需要一些代码,但它至少没有主题ID的硬编码,... - &gt;使用此代码段更新了我的getThemedStyle
public static int getThemedStyle(int normalStyle) {
Resources.Theme theme = appContext.getTheme();
TypedValue styleID = new TypedValue();
if (theme.resolveAttribute(R.attr.TextAppRed, styleID, true)) return styleID.data;
else return normalStyle;
} //getThemedStyle