I'm trying to get a color from a selector like this
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_checked="true"
android:color="#color/white" />
<item
android:state_checked="false"
android:color="#80FFFFFF" />
</selector>
By calling
ContextCompat.getColorStateList(context, R.drawable.bottom_navigation_colors_white)
But it produces Expected resource of type color error which is highlighted as error (highted in red) but but does not prevent from compiling.
What is wrong with this?
I have added BottomNavigationView in my application like.
main.xml
<com.google.android.material.bottomnavigation.BottomNavigationView
android:layout_width="match_parent"
android:layout_height="56dp"
app:itemBackground="#drawable/nav_bgcolor"
app:itemIconSize="50dp"
app:itemIconTint="#color/nav_item_colors"
app:itemTextColor="#color/nav_item_colors"
app:labelVisibilityMode="unlabeled"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="#menu/nav_items">
</com.google.android.material.bottomnavigation.BottomNavigationView>
menu/nav_items.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/nav_home"
android:icon="#drawable/home_white"
android:title="#string/nav_home" />
<item
android:id="#+id/nav_market"
android:icon="#drawable/market_white"
android:title="#string/nav_market" />
<item
android:id="#+id/nav_news"
android:icon="#drawable/news_white"
android:title="#string/nav_news" />
<item
android:id="#+id/nav_account"
android:icon="#drawable/account_white"
android:title="#string/nav_account" />
</menu>
drawable/nav_bgcolor.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#FF9800" android:state_checked="true" />
<item android:drawable="#FFFFFF" android:state_checked="false" />
</selector>
color/nav_item_colors.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#FFFFFF" android:state_checked="true"/>
<item android:color="#727272"/>
</selector>
this is the preview in the android studio
https://drive.google.com/file/d/1yICxFcTbSxYpILDtxg75Z4x-2Y1UaPM_/view?usp=sharing
it is actually displaying the design that i want to happen.
there is no error or something but when i run the app there are errors in drawable/nav_bgcolor.xml
C:\Users\[PCNAME]\AndroidStudioProjects\[APPNAME]\app\src\main\res\drawable\nav_bgcolor.xml:3: AAPT: error: '#FF9800' is incompatible with attribute drawable (attr) reference.
C:\Users\[PCNAME]\AndroidStudioProjects\[APPNAME]\app\src\main\res\drawable\nav_bgcolor.xml:4: AAPT: error: '#ffffff' is incompatible with attribute drawable (attr) reference.
the error happened after i added app:itemBackground="#drawable/nav_bgcolor" in the main.xml
I have searched the internet but no luck in getting any solution.
In your selector you are using
<selector>
<item android:drawable="#FF9800" android:state_checked="true" />
You can't use a color (#FF9800) where you should define an android:drawable.
Use
<menu>
<item
android:id="#+id/nav_home"
android:icon="#drawable/icon_add"
android:title="#string/nav_home" />
...
</menu>
where icon_add is a simple drawable.
And in your BottomNavigationView:
<com.google.android.material.bottomnavigation.BottomNavigationView
app:itemIconTint="#color/nav_item_colors"
../>
replace android:drawable with android:color in drawable/nav_bgcolor.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#FF9800" android:state_checked="true" />
<item android:color="#FFFFFF" android:state_checked="false" />
</selector>
I have the following problem:
My app has a light and a dark theme and I'm trying to apply touch feedback to some custom views for both above and below v21 (ripple touch feedback). I've created two drawable resources in drawable-v21 for a toggle button, one for light and one for dark:
Dark:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/color_control_highlight_default">
<item android:id="#android:id/mask" android:drawable="#drawable/dark_button_border"/>
<item android:drawable="#drawable/button_toggle_states"/>
</ripple>
Light:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/color_control_highlight_default">
<item android:id="#android:id/mask" android:drawable="#drawable/light_button_border" />
<item android:drawable="#drawable/button_toggle_states" />
</ripple>
As can be seen both resources reference another drawable which defines the colours for different states of the buttons:
button_toggle_states:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?attr/color_primary_1" android:state_focused="true" />
<item android:drawable="?attr/color_primary_1" android:state_checked="true" />
<item android:drawable="?attr/color_primary_1" android:state_selected="true" />
<item android:drawable="?attr/button_border" />
</selector>
This drawable references attributes that change between the light and the dark theme and this is where my problem is. When trying to use this drawable I get a runtime error that the button_toggle_states in res/drawable-v21 can't be found. When I change the drawable to reference colours and other drawables instead of attributes, i.e.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/lt_blue" android:state_focused="true" />
<item android:drawable="#color/lt_blue" android:state_checked="true" />
<item android:drawable="#color/lt_blue" android:state_selected="true" />
<item android:drawable="#drawable/light_button_border" />
</selector>
everything works fine. But with that solution I'll have to make two button_toggle_state files, one for dark and one for light theme, while I thought this shouldn't be needed since we can reference attributes in v21 and up.
Is there somethin I'm doing wrong or is referencing attributes in a drawable that is used by another drawable just not supported?
i ran into the same issue and was not able to get this running. My workaround is to have the drawable itself as a reference in the theme and then have two Drawables: one for light and one for dark.
See also:
https://code.google.com/p/android/issues/detail?id=26251
How to reference colour attribute in drawable?
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 libs:
compile 'com.android.support:appcompat-v7:+'
compile 'com.android.support:cardview-v7:+'
compile 'com.android.support:design:22.2.0'
Here is the source code for drawable:
<?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>
in this same code, if i replace attributes with colors defined in colors.xml file, the same drawable works.
Sample drawable with colors:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/color_primary" android:state_enabled="true" android:state_window_focused="false"/>
<item android:drawable="#color/color_primary_dark" android:state_pressed="true"/>
<item android:drawable="#android:color/darker_gray" android:state_enabled="false"/>
<item android:drawable="#color/color_primary"/>
</selector>
Thanks in advance!
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?
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!!
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 :-)
I ran into a similar problem while using attributes for color in a drawable selector.
I solved it by making a color selector instead of a drawable selector.
Basically, make a new resource, with Resource Type as Color, which will be your color selector. Here, unlike with drawable selectors, you can use your attributes without issue:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?colorBackgroundDisabled" android:state_enabled="false" />
<item android:color="?colorBackground" />
</selector>
^I named this selector_background.
Then you can use that selector:
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/selector_background"/>
In stead of putting a "?" Change it to "#"
android studio show me: element selector must be declared,why?
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/rd_btn_press"
android:state_pressed="true" />
<item android:drawable="#drawable/rd_btn"
android:state_focused="true" />
<item android:drawable="#drawable/rd_btn" />
</selector>
Make sure you have this file in the res/drawable folder. It seems to me that you have it in some other folder in android project. Please comment if that's not the case.