覆盖引用的样式属性

12

阅读完主题属性引用后,我想引用我设置的自定义主题中属性的值。

我正在将用户定义的样式应用于CheckedTextView

<CheckedTextView
    android:id="@+id/contactInfo"
    style="@style/ListViewCheckedTextViewRowStyle" >
</CheckedTextView>

用户自定义样式定义如下:

<style name="ListViewCheckedTextViewRowStyle" parent="@style/ListViewRowStyle">
    <item name="android:checkMark">?android:listChoiceIndicatorMultiple</item>
</style>

我创建的主题被定义为:

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

然而,显示出来的checkMark样式是设备默认主题的drawable而不是我的用户定义的drawable。

唯一一种我能让我的drawable显示出来的方式是:

<style name="ListViewCheckedTextViewRowStyle" parent="@style/ListViewRowStyle">
    <item name="android:checkMark">@drawable/btn_check_holo_light</item>
</style>

但这样做会完全打败覆盖此属性的整个目的,特别是因为我想在多个主题中覆盖此属性。

我正在使用以下代码在我的ActivityonCreate()方法中设置主题:

public void onCreate(Bundle savedInstanceState) {
    this.setTheme(R.style.Theme_Yellowgreen);
    super.onCreate(savedInstanceState);
    // ...
}

我也尝试在AndroidManifest.xml文件中设置主题,例如:

<application android:theme="@style/Theme.Yellowgreen" >

但是那样没有起作用。可能出了什么问题?

更新

我刚刚创建了一个小的示例项目,看起来我上面发布的代码是可以工作的。所以我肯定有其他的样式覆盖了这个属性,或者可能与我的布局xml文件有关。

在我的大型项目中,我有两个Fragment位于一个Activity中。两个Fragment都有由Adapters支持的Listviews。在Fragment A中,AdaptergetView()方法如下:

public View getView(final int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.contact_entry, null);
    }

    //...

    return convertView;
}

片段B中,AdaptergetView()方法如下:

public View getView(final int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.list_item, parent, false);
    }

    //...

    return convertView;
}

布局定义如下:

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/list_item"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    
    <include layout="@layout/list_item_header" />
    
    <include layout="@layout/contact_entry" />

    <View android:id="@+id/list_divider"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="@android:drawable/divider_horizontal_dark" />

</LinearLayout>

list_item_header.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/header_text"
    android:layout_width="match_parent"
    android:layout_height="25dip"
    android:background="@color/dark_blue"
    android:gravity="center_vertical"
    android:paddingLeft="6dip"
    android:textColor="@color/white"
    android:textSize="14sp"
    android:textStyle="bold" />

contact_entry.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/contactEntry"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:orientation="horizontal" >

    <QuickContactBadge
        android:id="@+id/contactPic"
        style="@style/ContactPicStyle" />

    <CheckedTextView
        android:id="@+id/contactInfo"
        style="@style/ListViewCheckedTextViewRowStyle" >
    </CheckedTextView>

</LinearLayout>

由于某种原因,在片段B中,主题化的checkMark属性无法正确地呈现,而在片段A中,checkMark使用当前的YellowGreen主题,并且被正确地样式化。为什么会发生这种情况?


你在清单文件中指定了_YellowGreen_主题吗? - dominus
如果你的主题名称是YellowGreen,为什么在清单文件中要写成@style/Theme.Yellowgreen呢?我对自定义主题并不是很了解,只是想搞清楚。 - Gokhan Arik
@GokhanArik,我更正了主题名称。这是原帖中的一个打字错误。 - Etienne Lawlor
尝试在onCreate之后调用setTheme。否则我不知道,在看到你的所有代码之前我无法发表任何评论。 - Gokhan Arik
什么是 ListViewRowStyle?这是在一个API级别上发生的还是一般行为? - user
显示剩余3条评论
1个回答

12

我认为你的主题需要那一行代码

<item name="android:checkedTextViewStyle">@style/ListViewCheckedTextViewRowStyle</item>

那么它会看起来像这样:

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

更新

经过问题更新和一些评论中的额外信息,我们发现问题出在Context上。这跟我在这个问题中犯的同样的错误有关:Android颜色选择器与自定义属性不起作用

一个片段传递了Activity,另一个传递了Application。虽然这两个类都扩展了Context,但只有Activity扩展了ContextThemeWrapper,其中包含有关样式的信息。未来理解上下文可能会有所帮助,请阅读这篇文章:http://www.doubleencore.com/2013/06/context/


嘿@Mikoos,我刚尝试将此属性添加到我的主题中,但不幸的是它无法覆盖属性android:listChoiceIndicatorMultiple - Etienne Lawlor
如果您在Github上提供了完整的示例项目,并注释说明您想要实现的具体内容,那么解决方案可能会更容易。我们可以使用poll request来提供解决方案。 - Mikooos
谢谢@Mikoos,我已经发布了更多的项目代码,并相信我正在接近找出问题所在。希望我提供了足够的细节。 - Etienne Lawlor
4
mInflater的上下文是什么?如果您使用context.getApplicationContext()将上下文传递给Adapter,它不会正确地进行样式设置。您需要传递Activity的上下文。 - Mikooos
谢谢 @Mikoos。我不小心将context.getApplicationContext()传递给了“B片段”,现已修复,最终样式正确。您能否更新您的答案并说明为什么必须传递Activity Context而不是Application Context?我会接受您的答案并奖励您的悬赏。 - Etienne Lawlor
再次感谢,@Mikoos,那篇文章解释得非常清楚。 - Etienne Lawlor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接