I have a ListView and each row uses a custom background color. I'd like to ensure that the default highlight is shown when the user touches a row, so I've defined a drawable with a selector, like this:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?android:attr/colorControlHighlight">
<item>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/clear" android:state_selected="true"/>
<item android:drawable="#color/clear" android:state_focused="true" android:state_pressed="true"/>
<item android:drawable="#color/clear" android:state_pressed="true"/>
<item android:drawable="#color/white"/>
</selector>
</item>
</ripple>
At first glance, it seems to work. However, if I scroll to a row that wasn't previously on the screen, the first time I tap the row, I don't get a ripple. But then if I tap it again, I do see the ripple. If I scroll the row off the screen and then back on again, same thing keeps happening.
Any ideas??
Thanks!!
I want to make a weekly calendar, where every day is a custom checkbox with objective to look like the image bellow:
(http://i.imgur.com/WjIKCd0.png)
When the user clicks on a day (Monday in this case), the "background" and "button" checkbox changes as well the text color...
I made the drawables and it seems to work fine... check bellow the code:
Checkbox layout:
<CheckBox
android:id="#+id/selectMonday"
android:layout_width="40dp"
android:layout_height="40dp"
android:button="#drawable/ic_none"
style="#style/CheckBoxBackgroundView"
android:onClick="selectDay"
android:text="#string/monday_letter"
android:gravity="center"
android:checked="true"/>
(the drawable "ic_none", is simple a 135x135 "transparent" image with nothing in it...)
Style (CheckBoxBackgroundView):
<style name="CheckBoxBackgroundView">
<item name="android:background">#drawable/background_day_week_picker_box_selector</item>
<item name="android:textColor">#color/text_color_day_week_picker_box_selector</item>
<item name="android:textSize">#dimen/text_spinner_text</item>
<item name="android:textStyle">bold</item>
</style>
Background Selector (background_day_week_picker_box_selector):
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="false"
android:drawable="#drawable/background_day_of_week_picker_unselected" />
<item android:state_checked="true"
android:drawable="#drawable/background_day_of_week_picker_selected" />
</selector>
Background selected (background_day_of_week_picker_selected):
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- view background color -->
<solid
android:color="#color/red_color" >
</solid>
<!-- view border color and width -->
<stroke
android:width="3dp"
android:color="#color/transparent">
</stroke>
<!-- Here is the corner radius -->
<corners
android:radius="10dp" >
</corners>
</shape>
and finally the color selector (text_color_day_week_picker_box_selector):
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="false"
android:color="#color/red_color"></item>
<item android:state_checked="true"
android:color="#color/white"></item>
</selector>
I tried this in several devices... in some, it appears like it suppose to, in others the text disappears and it looks like this:
(http://i.imgur.com/Jy9FrPS.png)
probably is coincidence, but all the devices that worked are below 5 inches...
is there anything wrong with my code that I'm not seeing? anyone have any suggestions?
Thanks in advance
The problem is that the 135x135 button drawable is pushing the text out of the bounds of your CheckBox's width. Instead of using a drawable, you can just set android:button="#color/transparent".
Currently I have a single button with image bound to it and I wanted to add a click effect on that(not click event, a effect). Well it worked fine. I created two xml in my drawable folder and added styles and gradient to it. But now I want to add few more buttons and apply the same click effect on them. One way I can create multiple xml files for as many buttons created. But what happened to code reuse? I want to reuse the same xml files for styling other buttons too. Can it be done? thanks in advance.
My button.xml file is:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:state_pressed="false" android:drawable="#drawable/stb" />
<item android:state_focused="true" android:state_pressed="true" android:drawable="#drawable/gradient" />
<item android:state_focused="false" android:state_pressed="true" android:drawable="#drawable/gradient" />
<item android:drawable="#drawable/stb" />
</selector>
And my gradient.xml is:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<bitmap android:src="#drawable/stb"/>
</item>
<item>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient android:angle="90" android:startColor="#990f0f10"
android:centerColor="#990d0d0f"
android:endColor="#995d5d5e"/>
</shape>
</item>
</layer-list>
You can set the very same xml selector drawable to as many views as you want. Just set the other button's background via XML:
android:background="#drawable/button"
or code:
yourSecondButton.setBackgroundResource(R.drawable.button);
I was wondering is there any way to make your customised ImageButton or a Button change background on click.
Now, I know that it can be done through XML doing something like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="#drawable/login_selected" /> <!-- pressed -->
<item android:state_focused="true"
android:drawable="#drawable/login_mouse_over" /> <!-- focused -->
<item android:drawable="#drawable/login" /> <!-- default -->
</selector>
Or in code, doing something like this, onClick:
public void onClick(View v) {
if(v == ButtonName) {
ButtonName.setImageResource(R.drawable.ImageName);
}
}
BUT, If I want to do it this way, that means I have to use 2 different images for one button. One with the normal and one with the pressed state.
That can be problem if I have, lets say, 100 different buttons.
That's 200 images, just for buttons.
You can Imagine resources saving with the ability of just telling eclipse it's a button, and I want it to go a bit darker, when I press it.
So I am asking is there a way of doing it like in Xcode ?
Setting up a background or an image of a button and it shades a bit when pressed, not changing the background or anything, just shading it a bit,
Try this code
if the name of
is btn_back.png
make the following darawble xml file
btn_semi.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="#50000011"
/>
<corners android:radius="10dip"/>
</shape>
btn_background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" >
<layer-list>
<item android:drawable="#drawable/btn_back"></item>
<item android:drawable="#drawable/btn_semi"></item>
</layer-list>
</item>
<item android:drawable="#drawable/btn_back"></item>
</selector>
Create a button in layout
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/btn_background"
/>
You can try to use setAlpha but its only available in API 11 and above
I have a drawable selector as a background for each item in a ListView to highlight the selected row. Eveything works fine in Ice Cream Sandwich, but doesn't seem to work in Jelly Bean. Can't find any documentation saying what changes could have caused it to stop working and what I need to do to fix it.
By not working, I mean when I click on a row in the ListView the item's background color isn't turning the #color/blue color, but it does in ICS.
This is the selector code I'm using (listing_selector.xml):
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_focused="true" android:drawable="#color/blue" />
<item android:state_pressed="true" android:drawable="#color/blue" />
<item android:state_activated="true" android:drawable="#color/blue_selected" />
<item android:state_selected="true" android:drawable="#color/blue_selected" />
<item android:drawable="#android:color/transparent" />
</selector>
This is the layout of the ListView item:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:background="#color/listing_selector"
>
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
/>
</RelativeLayout>
This the blue color resource:
<resources>
<color name="blue">#ff33b5e5</color>
</resources>
UPDATE 1:
Tried moving the selector from the color folder to the drawable folder and updating the code to this:
android:background="#drawable/listing_selector"
UPDATE 2:
Also, on the ListView, tried adding this:
<ListView android:id="#android:id/list"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:listSelector="#drawable/listing_selector"
/>
UPDATE 3:
I thought it might be something in my code, but I removed all the code from onListItemClick of the ListView and still the selector isn't working.
UPDATE 4:
I've narrowed it down to state_selected or state_activated not working as, state_pressed seems to be working
UPDATE 5:
I think I was mistaken. I don't think the selector is being recognized, at all. I was confusing the built-in ListView highlighting as my selector. I'm now wondering if it has something to do with the way my project is setup. I have the selector in a Library Class. Maybe something changed with that from ICS to JB, however moving the selector to my app's project didn't seem to fix it.
UPDATE 6:
Ok, after some more hair pulling, I've narrowed it down, again, to either state_selected or state_activated not being recognized, as changing the color for state_pressed does work, which means my selector is being recognized. From the comments in seems to be something with my app specifically as others have been able to get selectors working with Jelly Bean.
Though something else that is interesting is that changing the drawable value for the default state is not recognized. Where I have color/transparent, I would think changing that to a color would cause the listing to change to that color, but it doesn't.
Also, this isn't working in ICS either.
UPDATE 7:
After even more hair pulling, I've discovered that long-pressing on a menu item results in that item's color being changed. Just clicking on an item still does not work. Not even sure what the means.
** Final Update:**
I give up, I removed the selector and am just refreshing the ListView on click and remembering the position clicked and highlighting it from code. Not ideal, but not worth the effort to try to fix.
Okay, i think its an issue with your selector. Try removing the state_focused and the state_activated. You could try this for your selector:
<!-- Disabled State -->
<item
android:state_enabled = "false"
android:state_focused = "true"
android:state_pressed = "true"
android:drawable="#android:color/transparent">
</item>
<item
android:state_enabled = "false"
android:state_focused = "true"
android:drawable="#android:color/transparent">
</item>
<!-- Pressed State -->
<item
android:state_pressed = "true"
android:state_focused = "true">
<shape>
<solid android:color="#color/blue"/>
</shape>
</item>
<item
android:state_pressed = "true"
android:state_focused = "false">
<shape>
<solid android:color="#color/blue"/>
</shape>
</item>
<!-- Normal State -->
<item
android:drawable="#android:color/transparent">
</item>
I found that I needed to use a shape object too instead of android:drawable, because on pre-ICS phones, the whole list will be highlighted that color instead of the pressed list item.
You can add in your state_selected code too, but I'm not sure how it will be used. Check out the default selector code for jelly bean for the states they use: list_selector_background.xml.
listing_selector.xml must be in res/drawable folder and set the android:background attribute of your RelativeLayout like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:background="#drawable/listing_selector"
>
I cant say the reason why its working in one version and not working in another, but I got a alternative solution.
Define your color as a drawable in resources
<?xml version="1.0" encoding="utf-8"?>
<resources>
<drawable name="blue">#00F</drawable>
...
</resources>
Use this color drawable in your selector
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#drawable/blue" />
...
...
</selector>
Try this and let me know.
From the API Docs:
Note: Remember that Android applies the first item in the state list
that matches the current state of the object. So, if the first item in
the list contains none of the state attributes above, then it is
applied every time, which is why your default value should always be
last (as demonstrated in the following example).
Thus, try to reorder the states of your selectors according to the suggested order. In your case that would be this:
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" android:drawable="#color/blue" />
<item android:state_focused="true" android:drawable="#color/blue" />
<item android:state_selected="true" android:drawable="#color/blue_selected" />
<item android:state_activated="true" android:drawable="#color/blue_selected" />
<item android:drawable="#android:color/transparent" />
</selector>
I think it works fine !!
your selector xml file code:-
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/gray" android:state_focused="true"/>
<item android:drawable="#color/gray" android:state_pressed="true"/>
<item android:drawable="#color/orange" android:state_activated="true"/>
<item android:drawable="#color/orange" android:state_selected="true"/>
<item android:drawable="#color/orange"/>
</selector>
now create a folder values-v16 under res folder and put this colors file in it.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="gray">#4f4f4f</color>
<color name="orange">#e26c0e</color>
</resources>
and then the listview :
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="20dp"
android:listSelector="#drawable/listing_selector" >
</ListView>
Hope this works ! Tested on version 4.1
This is a very old question but I am still supporting Jellybean and I've noticed for background selectors to work I need to do something in particular. If I have a viewgroup with a background drawable and I need selector colors on it I need to do things in this order:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/my_drawable_button"/>
my_drawable_button must now reference a selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/primary_background_pressed"
android:state_pressed="true" />
<item android:drawable="#drawable/primary_background"
android:state_enabled="true" />
<item android:drawable="#drawable/primary_background_disabled"
android:state_enabled="false" />
</selector>
primary_background.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="8dp" />
<solid android:color="#color/secondary" />
</shape>
The others are the same with different colors. This is an awful lot of code to do something very basic, but I have found on Jellybean it's the only solution.
Future API levels allow you to specify the color selector on the drawable solid itself, eliminating 4 files:
post api 21:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/purple">
<item>
<shape android:shape="rectangle">
<corners android:radius="8dp" />
<solid android:color="#color/button_selector" />
</shape>
</item>
</ripple>
button_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/gray" android:state_enabled="false"/>
<item android:color="#color/secondary"/>
</selector>