Overriding referenced style attributes
Asked Answered
Z

1

12

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?

Zebulun answered 14/6, 2013 at 8:6 Comment(8)
Have you specified your YellowGreen theme in the manifest?Effeminacy
I've just created a sample project to test your style files and everything works fine for me. So I second dominus' question: have you set activity theme to YellowGreen in the manifest?Hanuman
hey @Effeminacy and @Idolon, I updated the question. I tried setting the activity theme two different ways but have been unsuccessful in overriding the android:listChoiceIndicatorMultiple style attribute.Zebulun
If your theme name is YellowGreen why did you put in manifest @style/Theme.Yellowgreen. I don't have much knowledge about customized themes, just trying to figure out.Armanda
@GokhanArik, I corrected the theme name. That was a typo in the original post.Zebulun
Try calling setTheme after onCreate. Otherwise I have no idea, I can't say anything before seeing your all code.Armanda
I have simplified my theme in the example i have provided in this post by excluding other attributes of the theme, but other attributes are being set properly, although they are not attributes that are being overridden.Zebulun
What is ListViewRowStyle? Also, this happens on one API level or it's a general behavior?Enclosure
N
12

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/

Nicaragua answered 19/6, 2013 at 7:30 Comment(6)
Hey @Mikoos, I just tried adding this attribute to my theme but unfortunately it doesn't override the attribute android:listChoiceIndicatorMultiple.Zebulun
It might be easier if you give us whole sample project on github with comments what exactly are you want to achieve. Solution could be given using poll request.Nicaragua
Thanks @Mikoos, I have posted more of my project's code and believe I am getting closer to finding out what's wrong. Hopefully I have provided enough details.Zebulun
What is the context of mInflater? If you passed context to Adapter using context.getApplicationContext() it wont style it properly. You need to pass Activities context.Nicaragua
Thanks @Mikoos. I unintentionally was passing the context.getApplicationContext() to Fragment B, I fixed this and it is finally styled correctly. Can you please update your answer and make a note about why you must pass Activity Context instead of Application Context and I will accept your answer and reward you the bounty.Zebulun
Thanks again @Mikoos, that article explains everything.Zebulun

© 2022 - 2024 — McMap. All rights reserved.