Databinding and ColorStateList Selector - android

I have a recycler view which I need to use one of the color selectors, depending on what value in the data binding, to change the TextView color.
I have two selectors:
color/selector_item_text.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/white" android:state_checked="true" />
<item android:color="#color/white" android:state_pressed="true" />
<item android:color="#color/white" android:state_activated="true" />
<item android:color="#color/black" />
</selector>
color/selector_item_textwithspecial.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/pink" android:state_checked="true" />
<item android:color="#color/pink" android:state_pressed="true" />
<item android:color="#color/pink" android:state_activated="true" />
<item android:color="#color/orange" />
</selector>
And I'm binding it to my TextView like this:
<TextView android:text="#{data.displayPrice}"
android:textColor="#{data.isSpecial ? #color/selector_item_textwithspecial : #color/selector_item_text}"
style="#style/ProductPrice"/>
The problem is that the TextView color is always orange (if it has special) or black. The selection never changes the color. However, if I remove the databinding, it worked as expected.
For example, the following will make TextView becomes pink (when selected) and orange (when not selected)
<TextView android:text="#{data.displayPrice}"
android:textColor="#color/selector_item_textwithspecial"
style="#style/ProductPrice"/>
Any idea how to tackle this problem?
Thanks...

Figured it out, see here
use android:textColor="#{data.isSpecial ? #colorStateList/selector_item_textwithspecial : #colorStateList/selector_item_text}"

I think you need to use ContextCompat to get the colors.
<TextView android:text="#{data.displayPrice}"
android:textColor="#{data.isSpecial ? #{ContextCompat.getColor(context, #color/selector_item_textwithspecial)} : ContextCompat.getColor(context, #color/selector_item_text)}"
style="#style/ProductPrice"/>
while context you need to declare in your root element in your xml file
tools:context="...."//path to your activity

Related

Disable highlight in ExpandableListView

I had been trying to disable the highlight in a ExpandableListView. I tried setting the next drawable as background, but this didn't work.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/_GREY_Weak"/>
<item android:drawable="#color/_GREY_Weak"
android:state_pressed="true" />
<item android:drawable="#color/_GREY_Weak"
android:state_selected="true" />
<item android:drawable="#color/_GREY_Weak"
android:state_focused="true" />
<item android:drawable="#color/_GREY_Weak"
android:state_checked="true" />
<item android:drawable="#color/_GREY_Weak"
android:state_long_pressable="true" />
<item android:drawable="#color/_GREY_Weak"
android:state_hovered="true" />
<item android:drawable="#color/_GREY_Weak"
android:state_expanded="true" />
</selector>
I tried setting each state drawable as that color, #null or transparent, but still the same. Here are some screenshots of my issue. I want to get rid of that highlight in the childrens as in the parent.
I also triead setting the property drawingCacheHint in the ExpandableListView xml with no luck.
Try adding
android:listSelector="#android:color/transparent"
in ExpandableListView xml
Or override the ExpandableListView style.

Android RadioButton textColor selector

I have a selector for textColor of a RadioButton like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:color="#fff"/>
<item android:state_focused="true" android:color="#f00"/>
<item android:state_pressed="true" android:color="#0f0"/>
<item android:state_focused="false" android:state_pressed="false" android:color="#00f"/>
</selector>
I expected that the one selected RadioButton will have different color than the others.
However, all of the RadioButtons have blue text (using android:state_focused="false" android:state_pressed="false"), even the one that is selected.
What am I doing wrong?
It looks like you're just using the wrong selectors. The docs describe selecting as follows:
During each state change, the state list is traversed top to bottom and the first item that matches the current state is used—the selection is not based on the "best match," but simply the first item that meets the minimum criteria of the state.
Source link
So, in order:
state_selected is never true as RadioButtons use state_checked
when checked.
state_focused is never called because RadioButton
will never receive input focus.
state_pressed should be working.
When you hold your finger down you don't see the text appearing
green?
state_focused false and state_pressed false ends up being
default so you see blue.
If you would like to see different states, try these:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="#0f0"/>
<item android:state_checked="true" android:color="#fff"/>
<item android:color="#00f"/>
</selector>
I have tested the above and can see all colors being expressed appropriately.
According to Android.
https://developer.android.com/guide/topics/resources/color-list-resource.html.
https://developer.android.com/reference/android/content/res/ColorStateList.html
You have to create a folder called 'color' in 'res' directory and create a new file called radiobuttonstate.xml for example which it looks like this.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true"
android:color="YOUR COLOR" />
<item
android:state_pressed="true"
android:state_enabled="false"
android:color="YOUR COLOR" />
<item android:color="YOUR COLOR"
android:state_checked="true"/>
<item
android:state_enabled="false"
android:color="YOUR COLOR" />
<item android:color="YOUR COLOR" />
</selector>
then in your radio button define in the android:textColor attribute your color list you previously defined.
<RadioButton
android:id="#+id/radio_H"
android:layout_width="30dp"
android:layout_height="30dp"
android:text="#string/string_example"
android:textColor="#color/radiobuttonstate"
android:textAlignment="center" />
The answer provided by #GrantAmos is perfect and working. If you want to text color selector through XML, please use this code.
android:textColor="#color/textview_selector"
However, if you want to set the selector programmatically, use this code -
radioButton.setTextColor(ContextCompat.getColorStateList(getContext(), R.color.textview_selector));
Hope it will save someone's time.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="false" android:drawable="#color/dark_grey"/>
<item android:state_checked="true" android:drawable="#color/topic_green"/>
</selector>
This one works for me. Actually when i use android:color="#color/dark_grey". It didn't work. But when i changed to drawable it did.
<style name="MyRadioButton" parent="Theme.AppCompat.Light">
<item name="colorControlNormal">#color/lbl_login</item>
<item name="colorControlActivated">#color/btn_login_back_color</item>
</style>
<RadioButton
android:id="#+id/btn_radio_credit_card"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/_8sdp"
android:fontFamily="#font/poppins_regular"
android:paddingStart="#dimen/_14ssp"
android:paddingEnd="#dimen/_1sdp"
android:text="Credit Card"
android:textColor="#color/lbl_login"
android:textSize="#dimen/_14ssp"
android:theme="#style/MyRadioButton" />
Refrence

Is it possible to create an xml subclass of a state list selector?

For example, say I have a color state list declared in XML, called example1.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:color="#color/red"
android:state_pressed="true" />
<item
android:color="#color/blue"
android:state_checked="true" />
<item
android:color="#color/green"
android:state_disabled="true" />
<item
android:color="#color/orange" />
</selector>
Then, I want to create example2.xml and I want it to be the exact same as example1.xml except I want the pressed color to be purple instead of red:
<item
android:color="#color/purple"
android:state_pressed="true" />
So example2.xml would end up acting like this:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:color="#color/purple" <-- note this value is different
android:state_pressed="true" />
<item
android:color="#color/blue"
android:state_checked="true" />
<item
android:color="#color/green"
android:state_disabled="true" />
<item
android:color="#color/orange" />
</selector>
but without all of the duplicate code. Also, if I want to change a color I can just change it in one place.
Is this possible?
I don't think you can do this on Android, You have to create multiple xml resources for different selector.

change button text color when pressed

I have made my button transparent so I would like to have the button text color change when the button is pressed. Is it possible to do this using just xml files?
Yes, you can do it like that:
layout/main_layout.xml:
.....
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="bonjour !"
android:textColor="#color/button_text_color"
/>
.....
color/button_text_color.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#c0c0c0" android:state_pressed="true"/>
<item android:color="#ffffff"/>
</selector>
See the section called State List in this bit of documentation...Drawable Resources.
You can define two different Button xml files one for the transparent 'default' state and another with the button as Red for your 'pressed' state. You then define a selector which switches the drawable resources in the different states.
EDIT: As per devunwired's comment the Color State List resource is probably more suitable for just changing colours rather than the drawable itself.
I like the solution proposed by Konstantin Burov in the other issue: Android customized button; changing text color
You can actually manage more states than just pressed and normal. But it should solve the problem.
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Focused and not pressed -->
<item android:state_focused="true"
android:state_pressed="false"
android:color="#ffffff" />
<!-- Focused and pressed -->
<item android:state_focused="true"
android:state_pressed="true"
android:color="#000000" />
<!-- Unfocused and pressed -->
<item android:state_focused="false"
android:state_pressed="true"
android:color="#000000" />
<!-- Default color -->
<item android:color="#ffffff" />
</selector>
Then you can use that selector drawable in your button changing the text color attribute like below. Note that the selector in the example below is named "button_text_color"
android:textColor="#drawable/button_text_color"
Using the same drawable approach you can also solve the background color of the button. Just remember that in the selector instead of using the "android:color" attribute you need to use the "android:drawable" attribute like below.
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Focused and not pressed -->
<item android:state_focused="true"
android:state_pressed="false"
android:drawable="#ffffff" />
<!-- Focused and pressed -->
<item android:state_focused="true"
android:state_pressed="true"
android:drawable="#000000" />
<!-- Unfocused and pressed -->
<item android:state_focused="false"
android:state_pressed="true"
android:drawable="#000000" />
<!-- Default color -->
<item android:drawable="#ffffff" />
</selector>
And then in the button itself do, note that this time the selector name is "button_background"
android:background="#drawable/button_background"
You have to do it in your code. Try this:
mBtn = ((Button) findViewById( R.id.button1 ));
mBtn.setOnClickListener( new OnClickListener() {
#Override
public void onClick(View v) {
mBtn.setTextColor( Color.RED );
}
});
Declare:
private Button mBtn;
You must set #drawable xml resource in textColor attributte
Here is example: Android customized button; changing text color
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="false"
android:color="#FFFFFF" />
<item
android:state_pressed="true"
android:color="#000000" />
</selector>

Android EditText native selector

I try to apply my own design to edittext and to use android native selector when my edittext is enabled, focused, etc. The problem is that every time I touch the edittext and the native selector is working my edittext becomes smaller. Can anyone please suggest why this is happening?Here is my code snippet:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_window_focused="false" android:state_enabled="true"
android:drawable="#android:drawable/edit_text"/>
<item
android:state_window_focused="false" android:state_enabled="false"
android:drawable="#android:drawable/edit_text"/>
<item
android:state_pressed="true"
android:drawable="#android:drawable/edit_text"/>
<item
android:state_enabled="true" android:state_focused="true"
android:drawable="#android:drawable/edit_text"/>
<item
android:state_enabled="true"
android:drawable="#android:drawable/edit_text"/>
<item
android:state_focused="true"
android:drawable="#android:drawable/edit_text"/>
<item
android:drawable="#drawable/my_border" />
</selector>
And here I use my selector:
<EditText
android:layout_height="37dip"
android:layout_width="fill_parent"
android:layout_marginLeft="7dip"
android:layout_marginRight="7dip"
android:background="#layout/selector_input"
android:paddingLeft="5dip"
android:paddingRight="5dip"
android:inputType="textEmailAddress">
</EditText>
This is the code of my_border:
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#color/white"/>
<stroke android:width="1dip" android:color="#color/border_green"/>
<corners android:radius="4dp" />
<padding android:left="1dip" android:top="1dip" android:right="1dip" android:bottom="1dip" />
</shape>
P.S. absolutely the same thing is happening with the buttons.
at first, thanks a lot for your post, helped me alot,
but your code above (sample for selector) wasnt working for me:
so i adapted it for others, so if someone searches howto mark a textfield as selected:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_window_focused="false" android:state_enabled="true"
android:drawable="#drawable/bottom_line_normal"/>
<item
android:state_window_focused="false" android:state_enabled="false"
android:drawable="#drawable/bottom_line_normal"/>
<item
android:state_pressed="true"
android:drawable="#drawable/bottom_line_focus"/>
<item
android:state_enabled="true" android:state_focused="true"
android:drawable="#drawable/bottom_line_focus"/>
<item
android:state_enabled="true"
android:drawable="#drawable/bottom_line_normal"/>
<item
android:state_focused="true"
android:drawable="#drawable/bottom_line_focus"/>
<item
android:drawable="#drawable/bottom_line_normal"/>
</selector>
have fun :=) good luck :)
Since no one was able to completely answer my question I will answer it by myself. The problem was that my edittext became smaller every time I touched it. That happens because native edittext background in Android has a transparent area around it. So I used a layer list to create my background also with a transparent area around it. Here is the code:
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:drawable="#drawable/transparent_background"
android:top="5dip"
android:right="5dip"
android:bottom="5dip"
android:left="5dip" />
<item
android:drawable="#drawable/my_border"
android:top="0dip"
android:right="0dip"
android:bottom="0dip"
android:left="0dip" />
</layer-list>
In my selector instead of my_border I use this xml.
That's it. Easy to do and hell difficult to find out how!
<item
android:drawable="#drawablemy_border" />
1. are you missing a slash [/]? And what is the definition of that drawable my_border
Ok, after I tried this files, the EditText doesn't use your selector when it's not enabled and appear with it's standard layout... so adding
<item
android:state_enabled="false"
android:drawable="#android:drawable/edit_text"/>
to your selector should be the solution

Categories

Resources