What is structure of a selector to define item - android

why we define this item in last
<item android:drawable="#drawable/twitter_im_edittext_normal" />
in a selector like this
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false"
android:state_enabled="true"
android:drawable="#drawable/twitter_im_edittext_normal" />
<item android:state_window_focused="false"
android:state_enabled="false"
android:drawable="#drawable/twitter_im_edittext_normal" />
<item android:state_pressed="true"
android:drawable="#drawable/twitter_im_edittext_normal" />
<item android:state_enabled="true"
android:state_focused="true"
android:drawable="#drawable/twitter_im_edittext_focused" />
<item android:state_enabled="true"
android:drawable="#drawable/twitter_im_edittext_normal" />
<item android:state_focused="true"
android:drawable="#drawable/twitter_im_edittext_focused" />
<item android:drawable="#drawable/twitter_im_edittext_normal" />
</selector>

See at the official documentation
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.

Think of a selector as a switch case. The statement are verified in the order they are listed, so the last one is your default: clause. In case your view doesn't match any of the conditions, it will default to
<item android:drawable="#drawable/twitter_im_edittext_normal" />

Related

Android strange list selector behaviour

I have a list where the list items have 2 clickable icon inside. The problem is that on Android 2.3 to Android 4.0.3 when I press a list item not only the row gets highlighted but also the icons are highlighted, but on Android > 4.1 this is not the case, here it works like it should, only the row gets highlighted.
The selector of my list:
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto">
<item android:state_window_focused="false" android:state_activated="false" android:drawable="#android:color/transparent" />
<item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="#drawable/list_selector_disabled_holo_light" />
<item android:state_focused="true" android:state_enabled="false" android:drawable="#drawable/list_selector_disabled_holo_light" />
<item android:state_focused="true" android:state_pressed="true" android:drawable="#drawable/dna_list_selector_background_transition_holo_light" />
<item android:state_focused="false" android:state_pressed="true" android:drawable="#drawable/dna_list_selector_background_transition_holo_light" />
<item android:state_focused="true" android:drawable="#drawable/list_focused_holo" />
<item android:state_activated="true" android:drawable="#drawable/list_longpressed_holo" />
And this is the selector of the icons:
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto">
<item android:state_window_focused="false" android:state_activated="false" android:drawable="#android:color/transparent" />
<item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="#drawable/list_selector_disabled_holo_light" />
<item android:state_focused="true" android:state_enabled="false" android:drawable="#drawable/list_selector_disabled_holo_light" />
<item android:state_focused="true" android:state_pressed="true" android:drawable="#drawable/dna_list_selector_background_transition_holo_light" />
<item android:state_focused="false" android:state_pressed="true" android:drawable="#drawable/dna_list_selector_background_transition_holo_light" />
<item android:state_focused="true" android:drawable="#drawable/list_focused_holo" />
I already searched a lot and tried to find out the problem but I am not getting it. Was the beheviour changed on Android 4.1?
The problem was that till exclusive android 4.1 the pressed state is also given to the children of the root list view and seeing that I defined following:
<item android:state_focused="false"
android:state_pressed="true"
android:drawable="#drawable/dna_list_selector_background_transition_holo_light" />
the icons in the list item is till android 4.1 pressed but not focused. I don't know if this is a bug or designed so, but it doesn't make sanse for me that the children also get the pressed state.
Starting with Android 4.1 the icons in the list item doesn't get the pressed state anymore.
Solution was to change the above selector to:
<item android:state_focused="false"
android:state_pressed="true"
android:drawable="#android:color/transparent" />

List item long press transition

This is what I use for list item selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
<item android:drawable="#color/red" android:state_pressed="true"/>
<!-- pressed -->
<item android:drawable="#color/green" android:state_pressed="false"/>
<!-- normal -->
</selector>
I have enabled a context menu for the ListView items so a users can long click on an item. What I want is that when a user long clicks an item, the colour should change from green to red. How can I achieve that?
You can use list_selector_background as it, As suggested here
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:drawable="#android:color/transparent" />
<!--
Even though these two point to the same resource, have two states so
the drawable will invalidate itself when coming out of pressed state.
-->
<item android:state_focused="true" android:state_enabled="false"
android:state_pressed="true" android:drawable="#drawable/list_selector_background_disabled" />
<item android:state_focused="true" android:state_enabled="false"
android:drawable="#drawable/list_selector_background_disabled" />
<item android:state_focused="true" android:state_pressed="true"
android:drawable="#drawable/list_selector_background_transition" />
<item android:state_focused="false" android:state_pressed="true"
android:drawable="#drawable/list_selector_background_transition" />
<item android:state_focused="true"
android:drawable="#+drawable/list_selector_background_focus" />
</selector>
And use a transition for long press, As suggested here:-
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/list_selector_background_pressed" />
<item android:drawable="#drawable/list_selector_background_longpress" />
</transition>
May be it will help you..

State list drawable and disabled state

I have a button and I want it to have different background when I set:
android:enabled="false"
Here's resource file for background:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false"
android:drawable="#drawable/bttn_orange_normal" /> <!-- pressed -->
<item android:state_pressed="true"
android:drawable="#drawable/bttn_orange_selected" /> <!-- focused -->
<item android:state_enabled="false" android:drawable="#drawable/bttn_grey_disabled"/>
<item android:state_enabled="true" android:drawable="#drawable/bttn_orange_normal"/>
</selector>
But button still has normal background when it is disabled.
What am I missing?
Put this line :
<item android:state_enabled="false" android:drawable="#drawable/bttn_grey_disabled"/>
as first item (it must be first item, otherwise it will not work) of the selector tag.
Final :
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:drawable="#drawable/bttn_grey_disabled"/>
<item android:state_pressed="false"
android:drawable="#drawable/bttn_orange_normal" /> <!-- pressed -->
<item android:state_pressed="true"
android:drawable="#drawable/bttn_orange_selected" /> <!-- focused -->
<item android:state_enabled="true" android:drawable="#drawable/bttn_orange_normal"/> <!-- idle state -->
</selector>
Vincent Ducastel's answer is correct, however it does not describe why the solution works.
When Android traverses the list of available items, it traverses the list from top to bottom, in each case evaluating whether the current state of the view matches the states defined for each item. It then selects the first item that matches the conditions and ignores the rest.
This is why you should always provide a default item at the bottom of the list and also provides a means of displaying complex selection conditions. For example if you wanted to have a special pressed state when the item is disabled, you would define the following items:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
...
<item android:state_enabled="false" android:state_pressed="false" android:drawable="#drawable/btn_grey_disabled"/>
<item android:state_enabled="false" android:state_pressed="true" android:drawable="#drawable/btn_white_disabled_selected"/>
...
</selector>
Added example of Active, Default and Disable State
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!--Disable-->
<item android:drawable="#drawable/ic_button_disable"
android:state_enabled="false"
android:state_pressed="false" />
<item android:drawable="#drawable/ic_button_disable_touch"
android:state_enabled="false"
android:state_pressed="true" />
<!--Default-->
<item android:drawable="#drawable/ic_button_default"
android:state_pressed="false"
android:state_selected="false" />
<item android:drawable="#drawable/ic_button_default_touch"
android:state_pressed="true"
android:state_selected="false" />
<!--Active-->
<item android:drawable="#drawable/ic_button_active"
android:state_enabled="true"
android:state_selected="true"
android:state_pressed="false" />
<item android:drawable="#drawable/ic_button_active_touch"
android:state_enabled="true"
android:state_pressed="true"
android:state_selected="true" />
</selector>

Keyboard background state

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="#drawable/key" />
<item
android:state_pressed="true"
android:drawable="#drawable/key_pressed" />
<item
android:state_checkable="true"
android:drawable="#drawable/key_function" />
<item
android:state_checkable="true"
android:state_pressed="true"
android:drawable="#drawable/key_pressed" />
<item
android:state_checkable="true"
android:state_checked="true"
android:drawable="#drawable/key_function" />
<item
android:state_checkable="true"
android:state_checked="true"
android:state_pressed="true"
android:drawable="#drawable/key_pressed" />
</selector>
test result:
normal key ->#drawable/key
normal key pressed ->#drawable/key_pressed
Sticky key->#drawable/key_function
Sticky key pressed ->#drawable/key_function <---here is the problem
The selection is not based on the "best match," but simply the first
item that meets the minimum criteria of the state.
http://developer.android.com/guide/topics/resources/drawable-resource.html#StateList
So it's the wrong drawable because one of those states is matching the current state
<item
android:state_checkable="true"
android:drawable="#drawable/key_function" />
<item
android:state_checkable="true"
android:state_checked="true"
android:drawable="#drawable/key_function" />
Try to put
<item
android:state_checkable="true"
android:state_checked="true"
android:state_pressed="true"
android:drawable="#drawable/key_pressed" />
at the top or add criterias to the previous cases.

Remove highlight effect from EditText

I want to remove the orange highlight around the EditText. This highlight doesn't match my UI and I really want to get rid of it.
Any ideas?
EditText uses selector for it's background.
From android source code:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:state_enabled="true"
android:drawable="#drawable/textfield_default" />
<item android:state_window_focused="false" android:state_enabled="false"
android:drawable="#drawable/textfield_disabled" />
<item android:state_pressed="true" android:drawable="#drawable/textfield_pressed" />
<item android:state_enabled="true" android:state_focused="true" android:drawable="#drawable/textfield_selected" />
<item android:state_enabled="true" android:drawable="#drawable/textfield_default" />
<item android:state_focused="true" android:drawable="#drawable/textfield_disabled_selected" />
<item android:drawable="#drawable/textfield_disabled" />
</selector>
You have to create you own selector where you can use your own drawables for pressed and selected state. You can read more about selectors here

Categories

Resources