I tried to create a selector for my button, using the the following XML codes...
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:constantSize="true">
<item android:drawable="#drawable/rectangular_transparent" android:state_enabled="true"></item>
<item android:drawable="#drawable/rectangular_grey" android:state_pressed="true"></item>
</selector>
this is the rectangular gray shape I have defined...
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#color/grey"/>
<stroke android:color="#android:color/transparent"/>
<corners android:radius="1dp"/>
</shape>
and this is the rectangular transparent shape I have defined...
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#android:color/transparent"/>
<stroke android:color="#color/grey" android:width="#dimen/_1sdp"/>
<corners android:radius="1dp"/>
</shape>
When I run it into my device, it shows only transparent button but it doesn't change color when i press...
The same approach works when I try to use with other color than transparent, please help...
The order of items in a selector is important. It always picks the first one that applies. So you should swap those items.
In your case, the button is always enabled, no matter what pressed state is, so it always picks the first item.
You need to use selector in right way :
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:constantSize="true">
<item android:drawable="#drawable/rectangular_transparent" ></item>
<item android:drawable="#drawable/rectangular_grey" android:state_pressed="true"></item>
or
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:constantSize="true">
<item android:drawable="#drawable/rectangular_transparent" android:state_pressed="true"></item>
<item android:drawable="#drawable/rectangular_grey"></item>
Related
After having been looking for a while I've not been able to find an answer to this...
I have a recycler view with items which when selected have a red background and white text (beforehand the background is white and text is black). To do this I am using a selector.
I have recently tried to add a ripple effect to this, but unless I long click on the item the background of the item goes straight to red without the ripple. I am assuming this is because the selector state state_selected overrides the ripple on sate_pressed?
Does anyone know if there is a way around this? Here is the selector code I use:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#android:color/holo_red_dark" >
<item>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:drawable="#drawable/ripple"
android:state_pressed="true"/>
<item
android:drawable="#android:color/holo_red_dark"
android:state_selected="true"/>
<item android:drawable="#android:color/white"/>
</selector>
</item>
</ripple>
Thanks in advance!
To create a selector background that has a ripple effect and shows selected status I do the following:
Start by defining your highlight color, with some transparency:
values/colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="selector_color">#660000ff</color>
</resources>
You probably want to have compatibility pre-lollipop. Put a typical old-school selector inside drawable folder:
drawable/selector_background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/selector_color" android:state_pressed="true"/>
<item android:drawable="#color/selector_color" android:state_selected="true"/>
<item android:drawable="#android:color/transparent"/>
</selector>
And then add the following layer drawable inside drawable-v21 folder:
drawable-v21/selector_background.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<selector>
<item android:state_selected="true"
android:drawable="#color/selector_color" />
<item android:drawable="#android:color/transparent" />
</selector>
</item>
<item>
<ripple android:color="#color/selector_color">
<item android:id="#android:id/mask">
<color android:color="#android:color/white" />
</item>
</ripple>
</item>
</layer-list>
Now you can use #drawable/selector_background for your selector.
So I have another case in which I had to use selector as well as layer list for that
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true">
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/colorRipple">
<item>
<layer-list>
<item>
<shape android:shape="rectangle">
<solid android:color="#color/grey_very_light" />
</shape>
</item>
<!-- ripple color -->
<item android:bottom="1dp">
<shape android:shape="rectangle">
<solid android:color="#color/c_unread_notifications_item" />
</shape>
</item>
</layer-list>
</item>
</ripple>
</item>
<item>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/colorRipple">
<item>
<!-- ripple color -->
<layer-list>
<item>
<shape android:shape="rectangle">
<solid android:color="#color/grey_very_light" />
</shape>
</item>
<item android:bottom="1dp">
<shape android:shape="rectangle">
<solid android:color="#color/white" />
</shape>
</item>
</layer-list>
</item>
</ripple>
</item>
</selector>
This worked, for your need what you can do it just replace the item under ripple with your item shape if you don't have any layering.
Hope this helps
It will be better if you wrap your recyclerview item view in FrameLayout and set android:background="?selectableItemBackground" of FrameLayout and the child layout of FrameLayout background="#drawable/background"
background.xml
<item android:drawable="#color/red" android:state_selected="true"/>
<item android:drawable="#color/red" android:state_focused="true"/>
<item android:drawable="#color/red" android:state_pressed="true"/>
<item android:drawable="#color/white"/>
And then child layout must has attribute android:duplicateParentState="true"
I want to put an underline to my selected side menu item.Is there any way to put only an underline to the item name instead of highlighting the whole item?
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
<item android:drawable="your drawable when pressed" android:state_pressed="true"/>
<item android:drawable="your drawable when selected" android:state_selected="true"/>
<item android:drawable="your drawable when activated" android:state_activated="true"/>
</selector>
The above code is a simple selector from where you can make the one that you need and you also need to add android:choiceMode="singleChoice" to your listview and also add the selector listView.setSelector(R.drawable.your_selector); or you can add in xml like android:listSelector="#drawable/your_selector"
A better selector for your need would be
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true">
<layer-list>
<item>
<shape>
<solid android:color="#ffffff" />
</shape>
</item>
<item android:bottom="3dp">
<shape>
<solid android:color="#ff0000" />
</shape>
</item>
</layer-list>
</item>
</selector>
Hope it helps a bit.
I had this working perfectly, although I need to change my code to listSelector, and now I don't know how to do it in order to maintain the border on left side.
In all listview lines I had one border:
border.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#E30E0E"/>
</shape>
</item>
<item android:left="5dip">
<shape android:shape="rectangle">
<solid android:color="#E3E3E3"/>
</shape>
</item>
</layer-list>
This sets the left side of each line, a border with color. But, as you can see, it has a default Solid color for background. With this code, whenever the user click on the item of the listview he doesn't understand if he has already clicked or not, because it has this solid color which doesn't change onState().
To make this working, I needed to create a listSelector with background gradients on state select plus state pressed.
selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_selected="false"
android:state_pressed="false"
android:drawable="#drawable/listview_gradient_bg"/>
<item android:state_pressed="true"
android:drawable="#drawable/listview_gradient_bg_hover" />
<item android:state_selected="true"
android:state_pressed="false"
android:drawable="#drawable/listview_gradient_bg_hover" />
</selector>
So, my question is: there's any way to "link" this two different piece of code?
Try to put this
<item android:left="5dip">
<shape android:shape="rectangle">
<solid android:color="#E3E3E3"/>
</shape>
</item>
into the listview_gradient_bg and listview_gradient_bg_hover drawables, then link the selector to each line in the adapter.
i've a list view with different colors depending on if it's an even or odd row:
My custom adapter:
if ( position % 2 == 0)
convertView.setBackgroundResource(R.layout.listview_selector_even);
else
convertView.setBackgroundResource(R.layout.listview_selector_odd);
list_selector_even:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#layout/even_row" android:state_enabled="true"/>
<item android:drawable="#layout/even_row" android:state_pressed="true"/>
<item android:drawable="#layout/even_row" android:state_focused="true"/>
</selector>
list_selector_odd:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#layout/odd_row" android:state_enabled="true"/>
<item android:drawable="#layout/odd_row" android:state_pressed="true"/>
<item android:drawable="#layout/odd_row" android:state_focused="true"/>
</selector>
even_row:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFF"/>
<padding android:left="3dp" android:top="3dp" android:right="3dp" android:bottom="3dp" />
</shape>
odd_row:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#F0F0F0"/>
<padding android:left="3dp" android:top="3dp" android:right="3dp" android:bottom="3dp" />
</shape>
I'm a little bit lost because i cant get the even and odd rows colors working with the gradient effect. For the preessed effect gradient i've the next code:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" >
<shape>
<gradient
android:startColor="#3E5260"
android:endColor="#3E5260"
android:angle="270" />
</shape>
</item>
</selector>
Thanks for the help!
You already check for the state in the selector, so for the gradient, you should do this instead:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#3E5260"
android:endColor="#3E5260"
android:angle="270" />
</shape>
Also, either change the selectors to following and define a file for each selector item, or move the selector with all available states to the odd_row.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#layout/odd_row_pressed" android:state_pressed="true"/>
<item android:drawable="#layout/odd_row_focused" android:state_focused="true"/>
<item android:drawable="#layout/odd_row_enabled"/>
</selector>
This version ensures that odd_row_enabled.xml is chosen if the item is not pressed and not focused. If you want another layout if the item is not enabled, you have to add one more line (before the default line). Also, it ensures that odd_row_pressed.xml is chosen in case it is pressed and enabled, because the <item> for the state pressed comes before the other lines.
Easy like itself . I wanna make an alpha button , which would have a selected drawable this way:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Play/Pause -->
<item android:state_selected="false" android:drawable="#drawable/item" />
<item android:state_selected="true" android:drawable="#drawable/item" />
</selector>
I would wanna make something like this:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Play/Pause -->
<item android:alpha="125" android:state_selected="false" android:drawable="#drawable/item" />
<item android:alpha="255" android:state_selected="true" android:drawable="#drawable/item" />
</selector>
Thanks for all .
It's been a while since the OP, but personally found a solution that worked a lot better for me than the suggested answers. Creating a BitmapDrawable makes is easily possible to set the alpha:
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/your_drawble"
android:alpha="77">
</bitmap>
Alpha can be any value between 0 and 255. Note that it is sort of the inverse of the HEX color value alpha, as for example 70% alpha would be B3 in HEX and 77 in the BitmapDrawable.
I achieved the same using a drawable
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="#5000ddff" />
</shape>
Over here used the alpha 50, which sets the opacity level.
I have been looking for the same thing. Even though this is posted over four years ago, this is the top post when googling the issue, so I'll reply here.
This is my solution
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false">
<bitmap android:alpha="#integer/not_pressed_alpha" android:src="#drawable/item"/>
</item>
<item android:state_pressed="true" android:drawable="#drawable/item" />
</selector>
For those who have the same problem as OP, AppCompat now allows you to set 'alpha' parameter, as he wished in his target code:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Play/Pause -->
<item android:alpha="125" android:state_selected="false" android:drawable="#drawable/item" />
<item android:alpha="255" android:state_selected="true" android:drawable="#drawable/item" />
</selector>
More info here.
My goal was to make a button have it's selected and pressed states at a different alpha - but using the same (png) resource and affecting as few files as possible.
My solution is similar to altering the alpha in a BitmapDrawable - but it does it from the selector so only one file is affected.
Use the tint function of Bitmap, remember that the tint will color the existing pixels so use a white color.
Eg, #80FFFFFF - to keep color as original but reduce alpha by 50%
This could also be used to change color of the icon when pressed.
This is my drawable XML file:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true">
<bitmap
android:src="#drawable/ic_camera"
android:tint="#80FFFFFF">
</bitmap>
</item>
<item android:state_pressed="true">
<bitmap
android:src="#drawable/ic_camera"
android:tint="#80FFFFFF">
</bitmap>
</item>
<item>
<bitmap
android:src="#drawable/ic_camera">
</bitmap>
</item>
</selector>
I'm using the following for a custom radio button which should be diagonally strikethrough when it is disabled.
Example Image of 5 radio buttons where 4 of them are enabled
<item android:state_enabled="false">
<layer-list>
<item>
<shape android:shape="rectangle">
<size
android:height="35dp"
android:width="35dp"/>
<stroke
android:color="#color/someGrey"
android:width="1dp"/>
<corners android:radius="1dp"/>
</shape>
</item>
<item>
<rotate
android:fromDegrees="135"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="135">
<shape android:shape="line">
<stroke
android:color="#color/someGrey"
android:width="1dp"/>
</shape>
</rotate>
</item>
</layer-list>
</item>
I agree with Kasium sugest, so for some Android versions the especification to Alpha is in percent.
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/your_drawble"
android:alpha="0.5">
</bitmap>
i think you could create your own drawable which could take this argument as a parameter. i've never done such a thing though.
check out this link :
How to set alpha value for drawable in a StateListDrawable?
if that's not possible, you can always do it in code...
here are 2 links i've found about it, in case you wish to use bitmaps instead:
https://plus.google.com/+RomanNurik/posts/FZQcNW8G75K
https://gist.github.com/romannurik/5779875
Its not that simple but its possible:
First you have to define color in color folder of your resources like this:
color/inst_control_pressed_transp.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:alpha="0.5" android:color="?attr/inst_control_pressed" />
</selector>
Now you can reference that color from some shape:
drawable/background_clear_pressed.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="#color/inst_control_pressed_transp" />
</shape>
Tha you can use it in drawable:
drawable/background_bordered_clear_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/background_clear_pressed" android:state_pressed="true" android:state_selected="false" />
<item android:drawable="#drawable/background_clear_active" android:state_activated="true" />
<item android:drawable="#drawable/background_clear_selected" android:state_selected="true" />
<item android:drawable="#drawable/background_bordered_clear_round" />
</selector>