How do I do this per selected list item.
I tried adding this to android:background
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true"
android:state_pressed="false"
android:drawable="#color/android_green" />
<item android:state_focused="true"
android:state_pressed="true"
android:drawable="#color/black_alpha" />
<item android:state_focused="false"
android:state_pressed="true"
android:drawable="#color/black_alpha" />
<item android:drawable="#color/white_alpha" />
</selector>
but it does not work, it changes the entire ListView.
Still not working, here is what I have so far
::listview_background
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:drawable="#color/black_alpha" />
<item android:drawable="#color/white_alpha" />
</selector>
::My view that is using the above
<ListView android:id="#+id/list" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_below="#+id/round"
android:listSelector="#drawable/listview_background">
</ListView>
The problem is that the black_alpha will apply the the entire list, not just the selected list item
Here's a good article on how to use selectors with lists.
Instead of setting it to be the android:background of the ListView, I believe you want to set android:listSelector as shown below:
<ListView android:id="#+id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:divider="#null"
android:dividerHeight="0dip"
android:listSelector="#drawable/list_selector" />
Jax, you said that:
The problem is that the black_alpha will apply the the entire list, not just the selected list item
I had the same problem. After playing around with it for a while, I was able to get it to stop applying the color to the whole list by using a 3x3 png image of the color I wanted instead of applying a color. So for some weird reason if you use a color you get the odd background behavior, when you use a png, it works fine. :S
So that is one way to get around it.
-----Another way----------
I found the best results when I set the listView selector to not have any states like this:
res/drawable/list_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
</selector>
Then I take care of all the states in the background of the list item. NOT in the selector. I found I had more control this way.
res/color/list_item_bg.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="#color/list_item_black_translucent" />
<item android:state_pressed="true"
android:drawable="#color/light_green_accent_translucent" />
</selector>
Then here is my list item:
res/layout/simple_list_item.xml
<?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:paddingRight="45dip"
android:paddingBottom="2dip"
android:layout_gravity="center_vertical"
android:background="#color/list_item_bg">
<ImageView
android:id="#+id/arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="8dip"
android:src="#drawable/list_item_arrow" />
<TextView
android:id="#+id/simple_list_item_label"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textSize="12sp"
android:textColor="#color/list_label_color"/>
</LinearLayout>
I was also facing your problem where the color change applies to the whole list.
But now its working for me now:
My main page containing the listview (noticed I did not apply the listselector here):
<ListView
android:id="#+id/controlList" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
Instead applied the listselector to getView, its like tell that particular row (convertView) to use the listselector.xml in drawable foldable when its state changes, e.g. pressed, focused...:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if(convertView == null){
LayoutInflater li = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
convertView = li.inflate(R.layout.control_list, null);
viewHolder = new ViewHolder();
viewHolder.topText = (TextView) convertView.findViewById(R.id.toptext);
viewHolder.bottomText = (TextView) convertView.findViewById(R.id.bottomtext);
convertView.setTag(viewHolder);
}
else{
viewHolder = (ViewHolder) convertView.getTag();
}
//each convertView will be assigned the listselector
convertView.setBackgroundResource(R.drawable.listselector);
viewHolder.topText.setText(testSchemes[position]);
//viewHolder.vText.setText(testDetails[position]);
return convertView;
}
And finally my listselector.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false"
android:state_selected="false"
android:drawable="#color/lightgreen" />
<!-- 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_pressed="true"
android:drawable="#color/darkgreen" />
<item android:state_selected="true" android:state_pressed="false"
android:drawable="#color/orange" />
</selector>
This is what the above code does:
All entries when first loaded are lightgreen.
Scrolling up and down using cursor highlights the selected entry orange.
Pressing a row turns it to darkgreen.
As bigstones mentioned in a comment, a working solution is using a shape instead of a color (I was also getting the whole list highlighted). Here is a complete solution:
add these 2 attributes to the listview:
android:drawSelectorOnTop="true"
android:listSelector="#drawable/my_list_selector"
add my_list_selector.xml to drawable folder:
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#77526F35"/>
</shape>
Now the list items should show a semitransparent green overlay on pressed state.
I faced the same issue and then I just needed a simple line in my item view xml.
android:background="?android:attr/activatedBackgroundIndicator"
Check this post: This post could help
Related
I have a ListFragment containing a multiple choice ListView. If I set the layout in my CursorAdapter to android.R.layout.simple_list_item_multiple_choice, I will be able to see the checked items in my ListView. But I want to use a custom layout and change the background color when the item is checked. It seemed rather simple but I couldn't find the answer to my problem. I thought about setting the color in the bindView of my adapter but I'm not sure it's where it belongs, since my adapter doesn't know which items are checked. So I tried to use a selector and apply it on the background of my textview like the following :
row.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceMedium"
android:minHeight="?android:attr/listPreferredItemHeight"
android:padding="6dp"
android:background="#drawable/list_selector"/>
list_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Pressed -->
<item android:state_pressed="true"
android:drawable="#drawable/list_pressed" />
<!-- Selected -->
<item android:state_selected="true"
android:drawable="#drawable/list_active" />
<!-- Checked -->
<item android:state_checked="true"
android:drawable="#drawable/list_active" />
<!-- Normal -->
<item android:drawable="#drawable/list_normal" />
</selector>
The pressed state is working but not the checked one. I wonder if my TextView is even checked at all. But if it's not, how does the ListView keep track of the checked items?
The source for android.R.layout.simple_list_item_multiple_choice uses a CheckedTextView, so you are on the right path. Just change the TextView in your layout to a CheckedTextView.
I have a listview, where I want to highlight selected items in a custom way. I'm setting every item properties in the adapter's getView method, including itemView.setSelected(true).
The main layout defines the listview in the following way:
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="multipleChoice"
android:listSelector="#drawable/list_selector" />
(Playing with choice mode does not help either).
The list_selector is an almost empty stub:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#android:color/transparent" />
</selector>
I don't need specific styles for listview as a whole, so I'd leave a default one, but according to this answer, we need a selector for a listview for item selector to work. Anyway, without the list_selector the problem remains.
The listview item layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:background="#drawable/listitem_background"
android:orientation="vertical">
and it references the following listitem_background selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="#android:color/white" />
<item android:drawable="#android:color/transparent" />
</selector>
The problem is, that selected items do not have white background.
If I change android:state_selected="true" selector in the listitem_background to, for example, android:state_pressed="true", then the selector starts to work, that is item background becomes white if an item is touched.
So, I suppose, there is an error either in the selectors, or in the way how I select items.
I can write a workaround by setting background from Java or utilizing checkable states, but I want to understand and fix current problem with selectors. Thanks in advance.
What about adding this line in your item view?
android:background="?android:attr/activatedBackgroundIndicator"
For instance:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/activatedBackgroundIndicator"
android:orientation="vertical" >
<TextView
android:id="#+id/textViewListRowOption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical" />
</LinearLayout>
Then the selector looks something like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:exitFadeDuration="#android:integer/config_mediumAnimTime">
<item android:drawable="#drawable/list_pressed" android:state_pressed="true"/>
<item android:drawable="#drawable/list_selected" android:state_activated="true"/>
<item android:drawable="#drawable/list_default"/>
</selector>
And the list view:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/listViewMainFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:listSelector="#drawable/list_item_selector"
android:choiceMode="singleChoice">
</ListView>
</LinearLayout>
Try this one to change the selected list item.Put it inside the list view.
if (currentSelectedView != null && currentSelectedView != v) {
unhighlightCurrentRow(currentSelectedView);
}
currentSelectedView = v;
highlightCurrentRow(currentSelectedView);
private void unhighlightCurrentRow(View rowView) {
rowView.setBackgroundColor(Color.TRANSPARENT);//to set a color for un-seclected row
}
private void highlightCurrentRow(View rowView) {
rowView.setBackgroundResource(R.drawable.selector_img);//to set a color for seclected row
}
My app has a grid view, By default, Its item does not highlight when I click on it (I don't know why? ). I try to add it a list selector as below, But it does not work too,
<GridView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_above="#+id/load_more_process_id"
android:layout_alignParentTop="true"
android:drawSelectorOnTop="false"
android:listSelector="#drawable/grid_selector"
>
</GridView>
Here my selector:
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" android:drawable="#android:color/black"></item>
<item android:state_pressed="false" android:drawable="#android:color/white"></item>
If you have a focusable element in the list item contents (or the views for each grid item), the selector isn't drawn
For example, if the template for your list items is:
<LinearLayout android:orientation="horizontal" ... >
<CheckBox android:id="#+id/checkBox" ... />
<TextView android:id+"#+id/textView" ... />
</LinearLayout>
then ListView will not draw a selector for each ListView item, because the CheckBox is, by default, focusable.
You can either provide a background on each item that changes with selection state, or disable focus on all focusable elements (which in turn requires you to write a fairy fancy adapter to check the checkboxes when selection state changes.
eg:
<CheckBox android:id="#+id/checkBox" android:focusable="false" ... />
will cause an enclosing ListView to start drawing the selector again.
Example of a stateful drawable:
drawable/my_list_selector_bg.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/list_background_pressed"
android:state_pressed="true" />
<item android:drawable="#drawable/list_background_focused"
android:state_focused="true" />
<item android:drawable="#android:color/transparent" />
</selector>
You then apply that to the background of each view returned by your adapter:
<LinearLayout android:orientation="horizontal"
android:background="#drawable/my_list_selector_bg"
... >
Either approach will work.
The list adpater classes (GridView, ListView, &c) call hasFocusable() on each view returned by the adapter, and disable selection drawing if hasFocusable() returns true. Fortunately, they also replicate the selection/focus/pressed/active state to the currently focused or selected adapter item, so you can draw it yourself if you want.
For those of you who are having the same issue I was, try
gridView.setDrawSelectorOnTop(true);
I have an ImageView and a TextView in each of my GridView items. My selector was working, but it was drawing behind my image.
Layout of grid view:
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:listSelector="#drawable/gridselector"/>
Create custom selector gridselector.xml like:
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/selector_item">
<item
android:state_pressed="true"
android:drawable="#drawable/focus_offfocus">
</item>
<item
android:state_enabled="true"
android:state_focused="true"
android:drawable="#drawable/focus_onfocus">
</item>
<item android:state_enabled="true"
android:drawable="#drawable/focus_offfocus">
</item>
</selector>
I have a ListView that has a selector set with just a solid color.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:id="#+id/assignmentSelectedItem" />
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/assignmentsListView"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
android:listSelector="#drawable/assignment_list_selector" />
</LinearLayout>
assignment_list_selector.xml -
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="#android:color/white" />
<item android:drawable="#android:color/transparent"/>
</selector>
In the ListView.Adapter for my list, I have items that have their view's background set to a specific color. My question would be is that why the selector is not working at all in displaying a selected color for my list view? If so, any suggestion of a work around with allowing me to still set the view's background color.
You can use ListView property android:drawSelectorOnTop="true" in your layout .xml file in order to made list view to draw the selector over the list item rather than under them.
If you wonna have item's background + list selector functionality you can try another approach: Use transparent list selector. And modify your selector in order to use as a background for the list item. For example
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="#android:color/white" />
<item android:drawable="#android:color/your_list_item_color"/>
</selector>
I am having problems defining a ListView with a custom adapter and list item xml layout. The problem is that my ListView is not highlight items when pressed. I am doing the following:
I define a drawable selector xml resource file:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" android:drawable="#android:color/holo_orange_light" />
<item android:state_pressed="false" android:drawable="#android:color/white" />
</selector>
I define an item layout xml file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#drawable/btn_voice_item"
>
<ImageButton
android:id="#+id/voiceItemFavorite"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_centerVertical="true"
android:layout_margin="5dp"
android:background="#drawable/btn_favorite" />
<TextView
android:id="#+id/voiceItemText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_margin="5dp"
android:layout_toRightOf="#+id/voiceItemFavorite"
android:background="#drawable/btn_voice_item" />
</RelativeLayout>
Finally I wrote code in my custom data adapter to inflate and populate then view.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = context.getLayoutInflater();
convertView = inflater.inflate(R.layout.voice_item, null);
}
VoiceItem i = getItem(position);
TextView t = (TextView) convertView.findViewById(R.id.voiceItemText);
t.setText(i.toString());
ImageButton b = (ImageButton) convertView.findViewById(R.id.voiceItemFavorite);
b.setTag(i);
b.setSelected(i.favorite);
b.setOnClickListener(new FavoriteClick());
return convertView;
}
Everything works except when I press items in the list there is no visual indication of the press. I expect the color of the pressed item's background to transition to the style defined by my drawable selector.
How can I both have a custom view items and retain styling highlighting of items while pressed?
If android:background="#drawable/btn_voice_item" is solid image so it'll cover the ListView selector. Here is very detail tutorial about custom ListView selector and item backround
ListViewTipsandTricks part3 (Cyril Mottier)
this is the xml i use. note that this is gradient. but put this in your #android:color/holo_orange_light
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#18d7e5"
android:centerColor="#16cedb"
android:endColor="#09adb9"
android:angle="270" />
</shape>
this is my selector:
<?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/gradient_bg" />
<item android:state_pressed="true"
android:drawable="#drawable/gradient_bg_hover" />
<item android:state_selected="true"
android:state_pressed="false"
android:drawable="#drawable/gradient_bg_hover" />
</selector>
and this is what i have in the list xml file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/list_selector"
android:orientation="horizontal"
android:padding="5dip" >
perhaps you find this useful and can work out your problem