48

我是 android 新手,我正在尝试为我的应用程序中的所有复选框设置样式。我的应用程序样式设置为 Theme.Holo,它是深色的,我希望列表视图上的复选框的样式为 Theme.Holo.Light。我不是在尝试创建自定义样式。下面的代码似乎不起作用,根本没有任何反应。我需要这样做,因为我的列表视图具有浅色纸张纹理,并且复选框和复选框文本是白色的,我想要深色。

<style name="CustomActivityTheme" parent="@android:style/Theme.Holo">
    <item name="android:checkboxStyle">@style/customCheckBoxStyle</item>
</style>

<style name="customCheckBoxStyle" parent="@android:style/Widget.Holo.Light.CompoundButton.CheckBox">
</style>

如果您为应用程序设置样式,您还可以为单个小部件设置样式吗?

4

5 回答 5

123

注意:使用 Android 支持库 v22.1.0 并针对 API 级别 11 及更高版本?向下滚动到最后一次更新。


我的应用程序样式设置为 Theme.Holo,它是深色的,我希望列表视图上的复选框的样式为 Theme.Holo.Light。我不是在尝试创建自定义样式。下面的代码似乎不起作用,根本没有任何反应。

起初,系统为什么会表现出这种行为可能并不明显,但当你真正研究机制时,你可以很容易地推断出它。让我一步一步地带你过去。

首先,让我们看看Widget.Holo.Light.CompoundButton.CheckBox样式定义了什么。为了让事情更清楚,我还添加了“常规”(非灯光)样式定义。

<style name="Widget.Holo.Light.CompoundButton.CheckBox" parent="Widget.CompoundButton.CheckBox" />

<style name="Widget.Holo.CompoundButton.CheckBox" parent="Widget.CompoundButton.CheckBox" />

如您所见,两者都是空声明,只是简单地包装Widget.CompoundButton.CheckBox在不同的名称中。因此,让我们看一下父样式。

<style name="Widget.CompoundButton.CheckBox">
    <item name="android:background">@android:drawable/btn_check_label_background</item>
    <item name="android:button">?android:attr/listChoiceIndicatorMultiple</item>
</style>

此样式同时引用背景和按钮可绘制对象。btn_check_label_background只是一个 9 补丁,因此在这个问题上不是很有趣。但是,?android:attr/listChoiceIndicatorMultiple表示基于当前主题的某些属性(这一点很重要)将决定CheckBox.

作为listChoiceIndicatorMultiple主题属性,您会发现它的多个声明 - 每个主题一个(或者如果它是从父主题继承的,则没有)。这将如下所示(为清楚起见省略了其他属性):

<style name="Theme">
    <item name="listChoiceIndicatorMultiple">@android:drawable/btn_check</item>
    ...
</style>

<style name="Theme.Holo">
    <item name="listChoiceIndicatorMultiple">@android:drawable/btn_check_holo_dark</item>
    ...
</style>

<style name="Theme.Holo.Light" parent="Theme.Light">
    <item name="listChoiceIndicatorMultiple">@android:drawable/btn_check_holo_light</item>
    ...
</style>

所以这才是真正神奇的地方:根据主题的listChoiceIndicatorMultiple属性,确定主题的实际外观CheckBox。您看到的现象现在很容易解释:由于外观是基于主题的(而不是基于样式的,因为这只是一个空定义)并且您继承自Theme.Holo,因此您将始终获得CheckBox与主题匹配的外观。

现在,如果您想将您CheckBox的外观更改为 Holo.Light 版本,您需要获取这些资源的副本,将它们添加到您的本地资产并使用自定义样式来应用它们。

至于你的第二个问题:

如果您为应用程序设置样式,您还可以为单个小部件设置样式吗?

当然,它们将覆盖任何活动或应用程序集样式。

有没有办法为复选框小部件设置主题(带图像的样式)。(...)反正有没有使用这个选择器:链接


更新:

让我首先再说一遍,你不应该依赖 Android 的内部资源。您不能随意访问内部命名空间是有原因的。

然而,访问系统资源的方法毕竟是通过名称进行 id 查找。考虑以下代码片段:

int id = Resources.getSystem().getIdentifier("btn_check_holo_light", "drawable", "android");
((CheckBox) findViewById(R.id.checkbox)).setButtonDrawable(id);

第一行实际上将返回btn_check_holo_light可绘制资源的资源 id。由于我们之前确定这是决定外观的按钮选择器CheckBox,我们可以在小部件上将其设置为“可绘制按钮”。结果是版本CheckBox的外观Holo.Light,无论您在 xml 中的应用程序、活动或小部件上设置什么主题/样式。由于这只设置了可绘制的按钮,因此您需要手动更改其他样式;例如关于文本外观。

下面是显示结果的屏幕截图。顶部复选框使用上述方法(我在 xml 中手动将文本颜色设置为黑色),而第二个复选框使用默认的基于主题的Holo样式(即非浅色)。

显示结果的屏幕截图


更新2:

随着支持库 v22.1.0 的引入,事情变得简单多了!发行说明中的​​引用(我的重点):

Lollipop 添加了通过使用 XML 属性在逐个视图级别覆盖主题的功能android:theme- 对于诸如轻活动上的深色操作栏之类的东西非常有用。现在,AppCompat 允许您使用android:theme工具栏(弃用app:theme之前使用的工具栏),甚至更好地android:theme支持 API 11+ 设备上的所有视图。

换句话说:您现在可以在每个视图的基础上应用一个主题,这使得解决原始问题变得更加容易:只需指定您想为相关视图应用的主题。即在原始问题的上下文中,比较以下结果:

<CheckBox
    ...
    android:theme="@android:style/Theme.Holo" />

<CheckBox
    ...
    android:theme="@android:style/Theme.Holo.Light" />

第一个CheckBox的样式就像在深色主题中使用一样,第二个好像在浅色主题中使用,无论为您的活动或应用程序设置的实际主题如何。

当然,您不应再使用 Holo 主题,而应使用 Material。

于 2012-04-13T11:15:58.773 回答
61

也许这会让你满意——

东西.xml

<CheckBox
    android:text="Custom CheckBox"
    android:button="@drawable/checkbox_selector"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

选择器

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true" android:drawable="@drawable/star_down" />
    <item android:state_checked="false" android:drawable="@drawable/star" />
</selector>

对于,参考只是参考here

于 2012-04-13T05:13:15.240 回答
36

材料设计的正确方法是:

风格 :

<style name="MyCheckBox" parent="Theme.AppCompat.Light">  
    <item name="colorControlNormal">@color/foo</item>
    <item name="colorControlActivated">@color/bar</item>
</style>  

布局 :

<CheckBox  
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:checked="true"
    android:text="Check Box"
    android:theme="@style/MyCheckBox"/>

它将保留 Lollipop+ 上的 Material 动画。

于 2016-04-14T12:28:08.633 回答
5

也许你想要类似的东西:

<style name="CustomActivityTheme" parent="@android:style/Theme.Holo">
    <item name="android:checkboxStyle">@style/customCheckBoxStyle</item>
</style>

<style name="customCheckBoxStyle" parent="@android:style/Widget.CompoundButton.CheckBox">
    <item name="android:textColor">@android:color/black</item>
</style>

注意,textColor 项。

于 2012-04-25T22:34:48.360 回答
1

在上一个答案中,<selector>...</selector>您可能还需要:

<item android:state_pressed="true" android:drawable="@drawable/checkbox_pressed" ></item>
于 2012-04-13T08:35:47.310 回答