i have a listview with a custom item_row.xml. I've defined a selector in this way:
<?xml version="1.0" encoding="utf-8"?>
<item
android:state_pressed="false"
android:drawable="#drawable/list_bg" >
</item>
<item
android:state_pressed="true"
android:drawable="#drawable/header_bg" >
</item>
<item
android:state_focused="false"
android:drawable="#drawable/list_bg" >
</item>
<item
android:state_focused="true"
android:drawable="#drawable/header_bg">
</item>
and then put into item_row.xml in this way:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="70dip"
android:orientation="vertical"
android:background="#drawable/list_selector">
I want 2 things:
When i move with arrow keys, the item selected changed its background. It's works fine with the actual implementation of selector.
When i press a item, the item changed its background too, but it doesn't work with the actual selector.
Any idea? I try to set also into the ListView android:listSelector="#drawable/list_selector"
but it doesn't work neither.
Thanks
You should model your StateListDrawable after the one used by Android itself for ListView selectors. You can find this in $ANDROID_HOME/platforms/$VERSION/data/res/drawable/list_selector_background.xml, where $ANDROID_HOME is where your Android SDK is installed and $VERSION is some Android version (e.g., android-2.1). Then, apply the list selector via android:listSelector in the ListView in your layout XML.
Related
I have a ListView which displays some inert items, so this should not change their backgrounds when a user touches the list view or item. This turns out hard to do:
What i have tried so far:
Java:
listView.setLongClickable(false);
listView.setClickable(false);
listView.setFocusable(false);
This has no effect what so ever. If I touch listview the background changes.
In the xml I tried;
<ListView
android:id="#android:id/list"
android:choiceMode="none"
android:clickable="true"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:listSelector="#null" />
Setting listSelector to #null is something I saw elsewehere on stack overflow. Does not work.
I also tried setting each item's background in code to transparent.
convertView.setBackgroundResource(R.color.transparent);
Nothing. On every touch there is always a change in background to blue.
How to make my listview not change item background on touch?
Try This, It works For Me
<ListView
android:listSelector="#android:color/transparent"
android:cacheColorHint="#android:color/transparent"
/>
You can set view.setEnabled(false); in your Adapter getView() - it will remove background effects.
You are probably using a layout for your list items that has a background which has a different selected state.
See what layout you use for the list items and change that to not include that background. If you are using the default (android.R.layout.simple_list_item) layout, you can create and use your own layout.
for this you need to make a custom background for the listview like
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_enabled="false"
android:drawable="#android:color/white" />
<item
android:state_pressed="true"
android:state_enabled="true"
android:drawable="#android:color/white" />
<item
android:state_focused="true"
android:state_enabled="true"
android:drawable="#android:color/white" />
<item
android:state_enabled="true"
android:drawable="#android:color/white" />
</selector>
place this xml file with name listbg.xml inside your drawable folder
<ListView
android:id="#+id/listt"
android:choiceMode="none"
android:clickable="true"
android:background="#drawable/listbg"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:listSelector="#null" />
I want make a list of Checkbox with white text in black background. We are using following code:
CheckBox chkAdditionalPack = new CheckBox(MainActivity.this);
chkAdditionalPack.setTag(j);
chkAdditionalPack.setText(offerPackageListForAddl.get(j).getOfferPackageName().toString());
chkAdditionalPack.setTextColor(Color.WHITE);
It gives a view like below:
The problem is now boxes of checkboxes is not clearly visible. How can I make it clearly visible keeping intact other parts?
If you are using android-studio, select your checkbox, and in the properties, set 'buttonTint' property value to whatever color you want using the editor. Or, if you prefer the XML solution, use
android:buttonTint="#color/white"
Note: This assumes that the color white is defined.
try the below xml code ref from solution
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_checked="true"
android:drawable="#drawable/cbchk_blue"
android:state_focused="false" >
</item>
<item
android:state_checked="true"
android:drawable="#drawable/cbchk_blue"
android:state_focused="true" >
</item>
<item
android:state_checked="false"
android:drawable="#drawable/cbunchk_blue"
android:state_focused="false" >
</item>
<item
android:state_checked="false"
android:drawable="#drawable/cbunchk_blue"
android:state_focused="true" >
</item>
</selector>
One really simple way to do it, within the xml for the checkbox, simply set the android:background variable to the colour you wish.
Instead of having the text and check box created together like this, simply create a custom list item layout xml file.
e.g custom_list_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#000000"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
/>
</LinearLayout>
Simply use this :
android:buttonTint="#FFFFFF"
** replace #FFFFFF with any color
The following problem is driving me crazy. I've defined an xml fragment, using this code:
<fragment class="host.helperclass.ServiceListFragment"
android:id="#+id/titles"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_width="0px"/>
Then I've implemented ServiceListFragment class which extends SherlockListFragment.
I've overridden the onActivityCreated method, with this code:
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
getListView().setDividerHeight(2);
getListView().setBackgroundColor(Color.parseColor("#EEEEEE"));
getListView().setCacheColorHint(Color.parseColor("#00000000"));
getListView().setSelector(R.drawable.list_selector);
Where list_selector.xml is very simple:
<?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/green"/>
<item android:state_focused="true"
android:drawable="#drawable/green"/>
<item android:state_selected="true"
android:drawable="#drawable/green"/>
</selector>
But the green background for an item is added only when I press the button. When I release it the green background is removed. It seems like the state_selected is not recognized.
Is this possible? If so, is there any way for enable the selection of items inside ListView?
NOTE:
I've also tried to use a selctor with only one item:
<item android:state_focused="true"
android:drawable="#drawable/green" />
And as result I obtaint that, when I press the ListView item the background become green, but when I release it the green background is removed. It seems that my item lost focus when I pull off my finger from item.
EDIT:
I have made another attempt.
I've added inside the onListItemClick method this line of code:
getListView().setItemChecked(index, true);
and in my xml selector I have put only this item:
<item android:state_checked="true"
android:drawable="#drawable/green" />
But strangely this does not work.
I believe the correct state for single choice mode is android:state_activated.
I noticed you are using the selector for the list.
You should use it as the background of the list row (the one you use in the adapter).
For example:
row_background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true"
android:drawable="#drawable/green"/>
</selector>
row_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/row_background">
<!-- your views -->
</LinearLayout>
Try this.
Add this item to selector
<item android:state_selected="true"
android:state_pressed="false"
android:drawable="#drawable/green" />
and remove
<item android:state_selected="true"
android:drawable="#drawable/green"/>
I found the problem.
Defining the xml layout for the row used in the custom adapter, I needed to add this row, to the root element:
android:background="?android:attr/activatedBackgroundIndicator"
But, the attribute activatedBackgroundIndicator has been introduced since API level 11, so I have put the previous version of my xml in layout folder, and the new one in the layout-v11 folder.
Also the following statement is required, inside the onListItemClick method:
getListView().setItemChecked(position, true);
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>
in drawable folder:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="#drawable/icon2" />
<item android:drawable="#drawable/icon3" />
</selector>
and the layout is just simple linear layout that fill the whole space
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:background="#drawable/on_touch_"
android:weightSum="1" android:focusable="true" android:focusableInTouchMode="true">
</LinearLayout>
and when I press this nothing happens
If I add, for example, some textview and assign android:background="#drawable/on_touch_" then that textview when pressed it changes the image correctly.
Where is the problem with the linear layout why it does not change the image when pressed ?
Edit:
I am sure that my drawable selector is good and working cause I put as a background to other elements and it is working.
But my problem is how to set the drawable to the root element
Add this to your layout :
android:clickable="true"
This will set the pressed state when you'll click it.
try out
save_selector.xml
<?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/save_hover_new" />
<item android:state_focused="true" android:state_pressed="true"
android:drawable="#drawable/save_hover_new" />
<item android:state_focused="false" android:state_pressed="true"
android:drawable="#drawable/save_hover_new" />
<item android:drawable="#drawable/save_new" />
</selector>
and give layout's background as selector like
android:background="#drawable/save_selector
I would make sure I do not have a drawable namesake. You seem to be using on_touch_.xml as your selector. Is there perhaps also an on_touch_.png?
I would also make sure that I am not setting the background again, to something else, or making it unclickable, in code.
I got a selector in a root element that is working fine; the background switches when pressed. It is not the root element of the activity layout, but it is the root element of the XML file.
The background is assigned with a png at first:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#drawable/panel"
>
...
I assign the background to the selector only when assigning an OnClickListener:
private void setClickListener(OnClickListener ocl) {
View boxRoot = findViewById(R.id.box_root);
if (ocl != null) {
boxRoot.setOnClickListener(ocl);
boxRoot.setBackgroundDrawable(getResources().getDrawable(R.drawable.panel_arrow_right_bgstate));
setClickable(true);
...
In my XML, I used android:clickable="true" but then I also added android:focusable="true" android:focusableInTouchMode="true" to match your case. That also worked fine, with background switching for all my four states.
// panel_arrow_right_bgstate.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="false" android:state_pressed="false" android:drawable="#drawable/panel_arrow_right_normal"/>
<item android:state_focused="false" android:state_pressed="true" android:drawable="#drawable/panel_arrow_right_pressed"/>
<item android:state_focused="true" android:state_pressed="false" android:drawable="#drawable/panel_arrow_right_selected"/>
<item android:state_focused="true" android:state_pressed="true" android:drawable="#drawable/panel_arrow_right_pressed"/>
If this is not working for you, something else is wrong with your code, somewhere else.
When I add or remove drawables, Eclipse sometimes gets fishy and mix them up. My normal measurements are:
Clean project
Refresh res folder in Eclipse
Delete gen\com.comp.proj\R.java