我有一个可以在运行时选择的具有两个主题(黑暗和浅色)的应用程序.这有效.我还有一个ListView,其行可以有三种不同的布局之一,每种布局都有一种样式(比方说,颜色不同).这也有效.但我不能让这两个功能一起工作.我真的需要六种不同的风格,三种为一种主题(黑暗),三种为另一种(浅色),但我无法弄清楚如何根据当前主题为列表项选择样式,或者获得任何效果通过使用XML文件的其他方式.我的三个布局都指向一个自定义主题设置颜色,但这会覆盖我设置的任何主题.主题只能包含"可设置"的项目,因此我无法将自己的自定义项目放在那里.可能有一种方法可以通过编程方式执行此操作,但我希望以声明的方式做到这一点.有任何想法吗?
由于僚机的提示.我的情况涉及颜色,这有点复杂,所以我会在这里写出我的解决方案.
我有两个主题(浅色和深色),用户可以在"设置"屏幕中选择.我有一个ListView可以有两种类型的行(普通和注释),每个行都有自己的样式.首先,每个布局都需要指向一种风格:
<TextView style="@style/PlainItemText" ... />
Run Code Online (Sandbox Code Playgroud)
(或NoteItemText)我们需要定义样式:
<style name="PlainItemText">
<item name="android:textSize">@dimen/list_item_font_size</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">?plainTextColor</item>
</style>
Run Code Online (Sandbox Code Playgroud)
无法修复文本颜色,因为它取决于所选主题.我们必须创建一个自定义属性并使用问号引用它,如上所述.我们在res/values/attrs.xml以下位置定义属性:
<!-- Attributes we use to set the text color of the various list items. -->
<attr name="plainTextColor" format="reference|color"/>
<attr name="noteTextColor" format="reference|color"/>
Run Code Online (Sandbox Code Playgroud)
然后我们可以定义各种颜色.这里我们有两个样式和两个主题,所以我们需要四个颜色状态列表,每个列表都位于自己的文件下res/color.例如,这里是res/color/plain_text_color_dark.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:color="@android:color/white"/>
<item android:state_selected="true" android:color="@android:color/black"/>
<item android:state_focused="true" android:color="@android:color/black"/>
<item android:state_pressed="true" android:color="@android:color/black"/>
<item android:color="@android:color/white"/>
</selector>
Run Code Online (Sandbox Code Playgroud)
所选/聚焦/按下的颜色在所有这些文件中都是相同的,因为它们超过了高亮颜色.小心state_window_focused版本.它没有像宣传的那样,我必须在所有情况下将其设置为默认颜色(上面的最后一行).现在我们需要创建主题并将属性绑定到其中一种颜色.这些行进入res/values/themes.xml:
<style name="Theme.Dark" parent="android:Theme">
<item name="plainTextColor">@color/plain_text_color_dark</item>
<item name="noteTextColor">@color/note_text_color_dark</item>
</style>
<style name="Theme.Light" parent="android:Theme.Light">
<item name="plainTextColor">@color/plain_text_color_light</item>
<item name="noteTextColor">@color/note_text_color_light</item>
</style>
Run Code Online (Sandbox Code Playgroud)
最后onCreate(),在调用之前,我们在Activity的方法中在运行时选择一个主题super.onCreate():
if (isDarkTheme) {
activity.setTheme(R.style.Theme_Dark);
} else {
activity.setTheme(R.style.Theme_Light);
}
Run Code Online (Sandbox Code Playgroud)
请注意,我没有考虑像Holo这样的新主题,所以我的应用程序在Honeycomb及更高版本上看起来很旧.我会在某些时候解决这个问题,但这不是回归.
在我的情况下,一个扭曲是一些活动有一个更大的标题栏,以适应一些按钮.原则上我应该创造四个主题,一个是明暗的标题,一个是明暗的标题.但相反,我创造了一种混合风格:
<!-- Mix-in style for activities. -->
<style name="ButtonTitleBar">
<item name="android:windowTitleSize">44dp</item>
</style>
Run Code Online (Sandbox Code Playgroud)
并在程序上将其添加到我正在使用的任何主题中.此代码在上述setTheme()调用后立即执行:
if (buttonTitleBar) {
// Mix in this other style.
Resources.Theme theme = activity.getTheme();
theme.applyStyle(R.style.ButtonTitleBar, true);
}
Run Code Online (Sandbox Code Playgroud)
我没有在任何地方看到这个记录,我不知道它是否合法,但代码Activity.getTheme()暗示它应该工作正常,并且它在我的所有测试中都有效.这有助于避免您在标准Android主题列表中找到的主题组合爆炸.
| 归档时间: |
|
| 查看次数: |
5843 次 |
| 最近记录: |