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>
Related
I used astuetz library and implemented PagerSlidingTabStrip for my android application, it's working find. Now I want to change pressing effect, I tried:
android:background="#drawable/tab_selecor"
Code for tab selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/darkGreen" android:state_focused="true" android:state_pressed="true" />
<item android:drawable="#color/darkGreen" android:state_focused="false" android:state_pressed="true" />
<item android:drawable="#color/green" />
</selector>
The press colour suppose to be changed to dark green but as you see it does not change, it still looks like this even if I use another colour like red, yellow, .... .
Make use of setIndicatorColor() for setting the color of indicator and setIndicatorHeight() for setting the height
And make use of setTabBackground() method to set the background to tab
Use this drawable for tab background
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Active tab -->
<item
android:state_selected="true"
android:state_focused="false"
android:state_pressed="false"
android:drawable="#color/red" /> <!-- Inactive tab -->
<item
android:state_selected="false"
android:state_focused="false"
android:state_pressed="false"
android:drawable="#android:color/black" />
<!-- Pressed tab -->
<item
android:state_pressed="true"
android:drawable="#android:color/transparent" />
<!-- Selected tab (using d-pad) -->
<item
android:state_focused="true"
android:state_selected="true"
android:state_pressed="false"
android:drawable="#android:color/transparent" />
</selector>
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" />
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" />
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 am creating a spinner with a custom view, anyway I managed to show different drawables for when the spinner is inactive and also for when it's pressed, I would like to keep the pressed state drawable when the dropdown list shows. Here is mi XML file:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true"
android:state_pressed="false"
android:drawable="#drawable/ComboBoxInactive" />
<item android:state_focused="true"
android:state_pressed="true"
android:drawable="#drawable/ComboBoxActive" />
<item android:state_focused="false"
android:state_pressed="true"
android:drawable="#drawable/ComboBoxActive" />
<item android:drawable="#drawable/ComboBoxInactive" />
</selector>
what state should I add for when it is displaying the dropdown? I want it to display ComboBoxActive drawable. I already tried adding this:
<item android:state_enabled ="false"
android:drawable="#drawable/ComboBoxActive"/>
Any idea of what the state is?
There is no android:state_dropdown_showing state.
The only one state on spinner dropdown list is state_enabled="true"
You can use my selector to differentiate dropdown list state
<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- disabled state -->
<item android:state_enabled="false" android:drawable="#drawable/spinner_off"/>
<!-- pressed state -->
<item android:state_enabled="true" android:state_window_focused="true" android:state_pressed="true" android:drawable="#drawable/spinner_pressed"/>
<!-- unselected state -->
<item android:state_enabled="true" android:state_window_focused="true" android:drawable="#drawable/spinner_default"/>
<!-- dropdown list state -->
<item android:state_enabled="true" android:state_focused="true" android:drawable="#drawable/spinner_dropdown_list_is_shown"/>
<!-- default -->
<item android:drawable="#drawable/spinner_default"/>
</selector>
Don't forget to set setFocusable and setFocusableInTouchMode properties on spinner.
Based on Olef Koshkin answer I can add that if you want save changed state after click to spinner and return it to default only after close spinner you can use. It works for me.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- disabled state -->
<item android:drawable="#drawable/custom_spinner_inactive"
android:state_enabled="false"/>
<!-- pressed state -->
<item android:drawable="#drawable/custom_spinner_inactive"
android:state_enabled="true"
android:state_pressed="true"
android:state_window_focused="true"/>
<!-- unselected state -->
<item android:drawable="#drawable/custom_spinner_inactive"
android:state_enabled="true"
android:state_window_focused="true"/>
<!-- dropdown list state -->
<item android:drawable="#drawable/custom_spinner_inactive"
android:state_enabled="true"
android:state_focused="true"/>
<!-- default -->
<item android:drawable="#drawable/custom_spinner_active"/>
</selector>
In other cases I see blink of default state and I didn't like it.
This works for me
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- For DropDown is Not Visible -->
<item android:drawable="#drawable/spinner_bg_with_arrow_border_theme_color" android:state_window_focused="false" />
<!-- For DropDown is enter code here Visible -->
<item android:drawable="#drawable/spinner_bg_with_arrow_border" android:state_window_focused="true" />
</selector>