Overriding referenced style attributes

toobsco42 picture toobsco42 · Jun 14, 2013 · Viewed 31.7k times · Source

After reading through References To Theme Attributes I am trying to reference the value of an attribute in the my custom theme that I have set.

I am applying a user-defined style to a CheckedTextView

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

The user-defined style is defined as :

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

My theme I created is defined as :

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

However, the checkMark styling that gets displayed is the device's default theme's drawable and not my user defined drawable.

The only way I can have my drawable displayed is with :

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

But that defeats the whole purpose of overriding this attribute, especially since I would like to override this attribute in multiple themes.

I am setting the theme in the onCreate() method of my Activity like this:

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

I also tried to set the theme in the AndroidManifest.xml file like :

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

But that didn't work. What could be going wrong?

Update

I just created a small sample project and it looks like the code i posted above is working. So i must have some other styles which are overriding this property or perhaps it has to do with my layout xml files.

In my large project, I have two Fragments within an Activity. Both Fragments have Listviews backed by Adapters. In Fragment A the getView() method of the Adapter is as follows:

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

    //...

    return convertView;
}

In Fragment B the getView() method of the Adapter is as follows:

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

    //...

    return convertView;
}

The layouts are defined as follows:

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>

For some reason, in Fragment B the themed checkMark attribute is not rendering correctly whereas in Fragment A, the checkMark uses the current YellowGreen Theme and is styled correctly. Why would this be happening?

Answer

Mikooos picture Mikooos · Jun 19, 2013

I think you need that line in your theme

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

so it would look like this:

<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>

UPDATE

After question update and some additional information form comments we found that the problem was in Context. It's the same mistake I did in that my question: Android color selector doesn't work with custom attributes

To one fragment was passed Activity and to the other Application. I'm not an expert but even both of those classes are extending Context only the Activity extends ContextThemeWrapper, which has information about styles. It might be helpful to read that article for future understanding Context: http://www.doubleencore.com/2013/06/context/