Android Selector Drawable doesnt work with attributes

后端 未结 4 1133
猫巷女王i
猫巷女王i 2020-12-14 12:13

I am using attr to create a selector drawable for my project so that once i change theme colors, i dont have to make any change in the drawable file. I am using following li

相关标签:
4条回答
  • 2020-12-14 12:53

    I encountered the same problem and as of 2019 it hasn't been resolved so you can't have an attribute referenced in a selector as a drawable. I will share the solution I got for the problem as I don't see it posted in here. I found it in the last comment of the bug report also referred by mudit in his answer.

    The workaround is basically create a drawable resource that will be the one referring the attribute value.

    To illustrate your case the solution would be instead of:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="?attr/colorPrimary" android:state_enabled="true" android:state_window_focused="false"/>
        <item android:drawable="?attr/colorPrimaryDark" android:state_pressed="true"/>
        <item android:drawable="@android:color/darker_gray" android:state_enabled="false"/>
        <item android:drawable="?attr/colorPrimary"/>
    </selector>
    

    you would replace the ?attr/* for a drawable resource:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@drawable/colorPrimaryDrawable" android:state_enabled="true" android:state_window_focused="false"/>
        <item android:drawable="@drawable/colorPrimaryDarkDrawable" android:state_pressed="true"/>
        <item android:drawable="@android:color/darker_gray" android:state_enabled="false"/>
        <item android:drawable="@drawable/colorPrimaryDrawable"/>
    </selector>
    

    The drawables would be defined as:

    drawable/colorPrimaryDrawable

    <shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle">
        <solid android:color="?attr/colorPrimary" />
    </shape>
    

    drawable/colorPrimaryDarkDrawable

    <shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle">
        <solid android:color="?attr/colorPrimaryDark" />
    </shape>
    

    Hope it helps!!

    0 讨论(0)
  • 2020-12-14 13:13

    Finally, found the problem. There is a bug in android [pre-lollipop] OS which doesnt allow you to use attr in drawable. Here is the link to bug:

    https://code.google.com/p/android/issues/detail?id=26251

    Android dev team has released a fix but it works on android L and above.For workaround to this problem, refer to following solution:

    How to reference style attributes from a drawable?

    0 讨论(0)
  • 2020-12-14 13:15

    In stead of putting a "?" Change it to "@"

    0 讨论(0)
  • 2020-12-14 13:17

    I dunno if it's still relevant to you, but I was struggling with the same thing and I think I have found a workaround (kinda). The direct use of ?attr/ is not working (working on api 21 and up, but even then it's not working with color selectors (only with drawables).

    So I did it like this (giving you my own example). Create an atribute in attr.xml

    <attr name="nav_item_color_selector" format="reference|color"/>
    

    Then in all the themes you're using, add the attribute like so (f.e. for the Light Theme):

    <item name="nav_item_color_selector">@color/text_color_selector_light</item>
    

    or for the dark theme(default):

    <item name="nav_item_color_selector">@color/text_color_selector</item>
    

    Now my text_color_selector.xml (both) look like this:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true"
          android:color="@color/myAccentColor" />
    <item android:state_selected="false" 
          android:color = "@color/myTextPrimaryColor"/>
    <item android:color="@color/myTextPrimaryColor" />
    

    and when I want to use them, f.e in tinting my custom image view, I use:

        <com.yourdomain.yourpackage.NavDrawerIcon
        android:layout_width="24dp"
        android:layout_height="24dp"
        android:layout_gravity="center_vertical"
        android:src="@mipmap/ic_launcher"
        android:id="@+id/nav_item_icon"
        android:layout_margin="24dp"
        android:tint = "?attr/nav_item_color_selector"
        android:tintMode="src_atop"/>
    

    You can also reitieve it programmatically by using TypedValue, like so:

        TypedValue typedValue = new TypedValue();
        Resources.Theme theme = context.getTheme();
        theme.resolveAttribute(R.attr.nav_item_color_selector, typedValue, true);
        XmlResourceParser parser = viewGroup.getContext().getResources().getXml(typedValue.resourceId);
        try {
            ColorStateList sl = ColorStateList.createFromXml(viewGroup.getContext().getResources(), parser);
            viewHolder.textView.setTextColor(sl);
    
        } catch (Exception e) {  }
    

    I hope this helps :-)

    0 讨论(0)
提交回复
热议问题