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" />
Related
I have the following selector.xml implementation, however, it only highlights when user clicks, however I want to be highlighted until other button clicks. How could I achieve it?
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_enabled="false"
android:drawable="#drawable/redo_off" />
<item
android:state_pressed="true"
android:state_enabled="true"
android:drawable="#drawable/redo_on" />
<item
android:state_focused="true"
android:state_enabled="true"
android:drawable="#drawable/redo_on" />
<item
android:state_enabled="true"
android:drawable="#drawable/redo_off" />
</selector>
Try defining an item for
android:state_selected="true"
as first item of your selector.
Edit :
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_selected="true"
android:drawable="#drawable/redo_on" />
<item
android:state_enabled="false"
android:drawable="#drawable/redo_off" />
<item
android:state_pressed="true"
android:state_enabled="true"
android:drawable="#drawable/redo_on" />
<item
android:state_focused="true"
android:state_enabled="true"
android:drawable="#drawable/redo_on" />
<item
android:state_enabled="true"
android:drawable="#drawable/redo_off" />
</selector>
I haven't tried it myself. If it doesn't work take a look at this similar post.
I have made three different images for a next button in my activity. A focused image, normal image and an image when the button is not enabled.
However, I wanted to test it and see how ot looks when it's not been enabled.
So on start I set it to false and it does work, I cannot touch it and it does not change to focused anymore, but the image does not change.
The ImageButton from my layout.
<ImageButton
android:id="#+id/nextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#null"
android:padding="5dp"
android:src="#drawable/nextbutton" />
The selector file nextbutton.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/btn_next_focused" android:state_focused="true" android:state_pressed="true"/>
<item android:drawable="#drawable/btn_next_focused" android:state_focused="false" android:state_pressed="true"/>
<item android:drawable="#drawable/btn_next_focused" android:state_focused="true"/>
<item android:drawable="#drawable/btn_next" android:state_focused="false" android:state_pressed="false"/>
<item android:drawable="#drawable/btn_next_disabled" android:state_enabled="false"/>
</selector>
What is wrong? It'll only change to focused and normal state but never to the disabled one. (I just noticed that it might be the wrong word for it...).
I found it out. I still don't know for sure why but I have a clue. I had to this line to every other item in the selector.
android:state_enabled="false"
So it looks like this :
<item android:drawable="#drawable/btn_next_focused" android:state_focused="true" android:state_pressed="true" android:state_enabled="false" />
<item android:drawable="#drawable/btn_next_focused" android:state_focused="false" android:state_pressed="true" android:state_enabled="false" />
<item android:drawable="#drawable/btn_next_focused" android:state_focused="true" android:state_enabled="false" />
<item android:drawable="#drawable/btn_next" android:state_focused="false" android:state_pressed="false" android:state_enabled="false" />
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..
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>
I have set a custom list selector for a Simple ListView but when I select an item, the whole ListView turns blue. I don't understand where the problem is.
This is my ListView:
<ListView android:id="#+id/TopListView" android:layout_width="fill_parent"
android:listSelector="#drawable/regular_selector"
android:layout_height="wrap_content">
</ListView>
and it's the regular_selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:state_focused="true"
android:drawable="#color/transparent" />
<item android:state_pressed="true"
android:drawable="#color/blue" />
<item android:state_focused="true"
android:drawable="#color/blue" />
</selector>
I was having the same issue of the whole list view highlighting, when using a color as the background. Curiously this only happened below api 11.
Solution was to use a solid shape drawable to wrap the colour:
list_selector_shaped_background_press.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="#color/list_selector_pressed"/>
</shape>
List_selector_background.xml
<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" />
<!-- this has to be in a shaped drawable otherwise the whole list is highlighted selects -->
<item android:state_focused="true" android:state_pressed="true"
android:drawable="#drawable/list_selector_shaped_background_pressed" />
<item android:state_focused="false" android:state_pressed="true"
android:drawable="#drawable/list_selector_shaped_background_pressed" />
<item android:state_focused="true"
android:drawable="#drawable/list_selector_background_focus" />
</selector>
I guess it is the usual problem. You have to set this in your listview:
android:cacheColorHint="#00000000"
The goal is to disable an optimization that the framework does for improving drawing performance during scrolling operations.
When I set the regular_selector.xml as listview item background it work!