I'm trying to create a selector that uses attributes defines by the selected theme.
attrs.xml
<declare-styleable name="ThemeColors">
<attr name="buttonTextColor" format="color" />
</declare-styleable>
selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" android:color="#android:color/black" />
<item android:color="?attr/buttonTextColor"/>
</selector>
Theme:
<style name="Theme.Test" parent="#style/Theme.AppCompat">
<item name="buttonTextColor">#android:color/white</item>
</style>
Part of the layout file:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/test"
android:textColor="#drawable/selector" />
Manifest
<application
...
android:theme="#style/Theme.Test" >
The layout file is inflated by the setContentView method.
Now the problem is that the textcolor is RED in the unpressed state (and black when pressed). It seems like it cannot find the buttonTextColor and uses the default RED(?)
Already tried to set the theme to the Application Context, but no luck..
Thanks in advance.
Related
I'm trying to create custom themes for my app and therefore, would like the selector to pick up the right drawable based on the current theme. Unfortunately, doesn't look like any image gets picked up at all.
This is my selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<bitmap android:src="?attr/test_a"
android:gravity="center" />
</item>
<item android:state_focused="true">
<bitmap android:src="?attr/test_a"
android:gravity="center" />
</item>
<item android:state_activated="true">
<bitmap android:src="?attr/test_a"
android:gravity="center" />
</item>
<item>
<bitmap android:src="?attr/test_b"
android:gravity="center" />
</item>
</selector>
My attributes are defined in attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="test_a" format="reference"/>
<attr name="test_b" format="reference"/>
</resources>
And my theme has the following:
<style name="MyTheme" parent="Theme.AppCompat.NoActionBar">
<item name="test_a">#drawable/test_a_dark</item>
<item name="test_b">#drawable/test_b_dark</item>
</style>
<style name="MyTheme.Light">
<item name="test_a">#drawable/test_a_light</item>
<item name="test_b">#drawable/test_b_light</item>
</style>
The theme is applied in the manifest as required. I have seen some questions on SO around this saying that there's a problem Pre-Lolipop, however, I'm testing on Marshmellow.
Still not sure why this happens but in case this is useful for someone, as a workaround I did the following:
1) Created two selectors - one for the dark theme, pointing directly at the dark drawables, and one for the light theme
2) Created one attribute with type reference
3) Modified the theme to use that attribute point at the selector instead of the drawable
I'm trying to find the best way to reuse resource files. In this example, I'm trying to create a ghost button for Android. I have a ghost button drawable xml file that defines the background, but I would like to be able to specify the color (specifically without using theme based defined colors).
ghost.xml:
<shape
android:shape="rectangle">
<corners android:radius="#dimen/ghost_button_corner" />
<solid android:color="#android:color/transparent" />
<stroke android:width="#dimen/ghost_button_stroke_size" android:color="?attr/ghost_color" /></shape>
ghost_style.xml:
<!-- STYLABLE -->
<attr name="ghost_color" format="reference" />
<!-- STYLES -->
<style name="GhostButtonBlack" parent="#style/GhostButton">
<item name="ghost_color">#android:color/black</item>
</style>
<style name="GhostButtonWhite" parent="#style/GhostButton">
<item name="ghost_color">#android:color/white</item>
</style>
<!-- BASE -->
<style name="GhostButton" parent="android:style/Widget.Button">
<item name="android:textSize">#dimen/ghost_button_text_size</item>
<item name="android:textColor">?attr/ghost_color</item>
<item name="android:background">#drawable/ghost</item>
</style>
within layout.xml:
<Button
style="#style/GhostButtonWhite"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_margin="5dp"
android:text="White Ghost Button" />
But I'm currently getting the following exception:
Caused by: java.lang.RuntimeException: Failed to resolve attribute at index 5
at android.content.res.TypedArray.getColorStateList(TypedArray.java:425)
at android.widget.TextView.<init>(TextView.java:987)
NOTE
I recognize this type of styling can be done via code. My ideal solution would involve no code; just resources.
I think you should get the GradientDrawable from your shape and apply a different color programmaticaly like this:
GradientDrawable mygrad = (GradientDrawable) view.getBackground();
color = inflater.getContext().getResources().getColor(yourcolorinstyles);
mygrad.setColor(color);
I'm trying to develop two themes for my app, and depending on the theme, I need a View to use a different selector. Though when I create a reference which determines the correct selector to use, I get an InflationException error.
Here's my attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ReditrTheme">
<attr name="downvoteArrow" format="reference" />
<attr name="upvoteArrow" format="reference" />
</declare-styleable>
<declare-styleable name="VoteState">
<attr name="enabled" format="boolean" />
</declare-styleable>
</resources>
Here's my themes.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="DarkTheme" parent="#android:style/Theme.Holo">
<item name="upvoteArrow">#drawable/upvote_states</item>
<item name="downvoteArrow">#drawable/downvote_states</item>
</style>
<style name="LightTheme" parent="#android:style/Theme.Holo.Light">
<item name="upvoteArrow">#drawable/upvote_states_l</item>
<item name="downvoteArrow">#drawable/downvote_states_l</item>
</style>
</resources>
Here's my upvote_states.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res/com.reditr.app">
<item android:drawable="#drawable/ic_action_arrow_top_colored" app:enabled="true"/>
<item style="#drawable/ic_action_arrow_top" app:enabled="false"/>
</selector>
Here's my upvotes_states_l.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res/com.reditr.app">
<item android:drawable="#drawable/ic_action_arrow_top_colored" app:enabled="true"/>
<item style="#drawable/ic_action_arrow_top_l" app:enabled="false"/>
</selector>
downvotes_states.xml and downvotes_states_l.xml are identical to the ones above, they just use ic_action_arrow_bottom instead.
Finally, here's my View that I'm trying to apply the reference to:
<com.example.views.UpvoteView
android:id="#+id/upvote"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:scaleType="fitCenter"
android:src="?attr/upvoteArrow" />
I tried a few solutions online but they were always a bit slightly different to my issue and didn't fix my problem.
Thanks in advance!
Just realized the mistake I made. In my states.xml files, I used the style attribute for some reason, it should have been android:drawable.
I'm using spinner and want to add spinner - to change behavior depends of states(focused, pressed)
sample project is here https://github.com/vovs/spinner_issue
My code:
activity_main.xml
<Spinner
android:id="#+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:spinnerMode="dropdown"
android:dropDownSelector="#drawable/spinner_state" />
spinner_state.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_enabled="false"
android:drawable="#color/black" />
<item
android:state_pressed="true"
android:state_enabled="true"
android:drawable="#color/red" />
<item
android:state_focused="true"
android:state_enabled="true"
android:drawable="#color/red" />
<item
android:state_enabled="true"
android:drawable="#color/gray" />
</selector>
AndroidManifest:
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="16" />
So, if I run app in emulator Android 4.0.2 API 14 and try to select some item or scroll using wheel of my mouse no any effect, that I set in selector(when press or scrolling - items should be red, but it is blue - default for ICS color).
For Android 2.2 API 8 when press or scroll using wheel(in this case state is focused) color is yellow[orange](default color for Android 2.2)
How to enable selector for spinner?
also an official bug...
https://code.google.com/p/android/issues/detail?id=24922
what helps:
<resources>
<style name="Theme.MyTheme" parent="#android:style/Theme.Holo.Light">
<item name="android:dropDownListViewStyle">#style/Theme.MyListView</item>
</style>
<style name="Theme.MyListView" parent="#android:style/Widget.Holo.Light.ListView">
<item name="android:listSelector">#drawable/orange_list</item>
</style>
</resources>
good luck!
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:drawable="#color/lighter_gray_no_transparent" />
<item android:state_selected="true" android:drawable="#color/lighter_gray_no_transparent" />
<item android:state_pressed="true" android:drawable="#color/lighter_gray_no_transparent" />
<item android:drawable="#android:color/transparent"/>
</selector>
<color name="lighter_gray_no_transparent">#FFDDDDDD</color>
set backgroud selector for your item view, that's all. Work for me. The color alpha value should be FF, or it will show orange background, left one color value is #FFDDDDDD, the right one is #55DDDDDD
There may be other ways but here's what I understand from using one of the Generators.
Declare your own style for the spinner in your res/values/styles.xml pointing to your drawable.
<style name="myCustomSpinner" parent="android:Widget.Holo.Light.Spinner">
<item name="android:background">#drawable/spinner_state</item>
</style>
Create res/values/themes.xml and declare your own theme that inherits from the current theme. Within this theme, add an item for each attribute you're modifying and point it to your custom style from the last step. I think this could go in the styles file if you wanted, but since the generator separates them I follow suit.
<style name="myCustomTheme" parent="android:Theme.Light">
<item name="android:dropDownSpinnerStyle">#style/myCustomSpinner</item>
</style>
In your AndroidManifest, add android:theme="#style/myCustomTheme" to the opening application tag.
Your values for parent will depend on how the project is setup and I think this will style of the spinners in your project and not just one. Try it out and let me know what you get.
I'm trying to use a color defined in a stlyle in a selector but it is causing a Resources$NotFoundException.
First I added a new attribute to attr.xml:
<resources>
<attr name="unread_background" format="color" />
</resources>
Then I defined that attr value in styles.xml:
<style name="ThemeNoTitleBar" parent="android:Theme.NoTitleBar">
<item name="unread_background">#000000</item>
</style>
Then I tried to use that attr in my selector definition:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- other states snipped -->
<item android:state_selected="false"
android:drawable="?unread_background" />
</selector>
Lastly, the activity uses the ThemeNoTitleBar style theme in the manifest.
I've also tried creating a color in colors.xml and having it use the new attr but that also fails.
I'm obviously missing something but am not sure what to do to fix it. My intent is to create multiple themes and have the selector use the color in the currently selected theme.
<item android:state_selected="false"
android:drawable="?unread_background" />
this above section is wrong.
the drawable only take a reference to a drawable resource.
Please see this link. http://developer.android.com/guide/topics/resources/drawable-resource.html#StateList
Here is something, that works by me.
attrs.xml:
<attr name="color_selection" format="reference"/>
styles.xml, as child of main theme:
<item name="color_selection">#color/selection_background_inverse</item>
shape_background_selected.xml in drawable folder:
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="?attr/color_selection"/>
</shape>
your selector file, in my case: selector_background_recyclerview:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/shape_background_selected" android:state_activated="true" />
<item android:drawable="#drawable/shape_background_selected" android:state_pressed="true" /> <!-- pressed -->
<item android:drawable="#color/transparent" /> <!-- default -->
</selector>
finally, in your view's xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#drawable/selector_recyclerview_item_background"../>
Android button with different background colors Take a look onto the example. It looks like you need that.