2

I have a ListView where I'm changing the background color of the selected item using the onListItemClick event:

@Override
public void onListItemClick(final ListView l, final View v, final int position, final long id)
{
    v.setBackgroundColor(Color.GRAY);
}

Is it possible to reset all of the rows of the ListView back to the original color before changing the single view's background color? The problem is that each selected item retains their background color and I only want the latest item the user clicked on changed.

UPDATE:

JRaymond's response seems to be the best approach, however, and it's usual when working with Android layouts, I've put the code in and nothing happens. No way to debug it, no error messages, nothing. I absolutely hate dealing with Android layouts, it's the most convoluted, terribly implemented design for dealing with UI.

Anyhow, this is what I have so far:

ListView:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"  
    android:layout_height="fill_parent" 
    > 

        <ListView android:id="@android:id/list"
            android:layout_width="wrap_content"  
            android:layout_height="fill_parent" 
            android:choiceMode="singleChoice"
            android:listSelector="@drawable/listing_selector"           
        />

        <TextView android:id="@android:id/empty"
            android:layout_width="wrap_content"  
            android:layout_height="fill_parent" 
            android:padding="5dp"
        />

</LinearLayout>

listing_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:drawable="@android:color/transparent" />
   
   <item android:state_pressed="true" android:drawable="@android:color/transparent" />

   <item android:state_selected="true" android:state_activated="true" android:drawable="@android:color/black" />
   
   <item android:state_activated="true" android:drawable="@android:color/transparent" />    
   
   <item android:state_selected="true" android:drawable="@android:color/transparent" />
   
   <item android:drawable="@android:color/transparent" />
   
</selector>

Like I said, nothing happens when I click on items, even the built-in highlighting is gone. I even tried changing all of the color to black, but nothing happens.

UPDATE2:

I'm getting closer. After reading this article, you have to place your selector xml in a folder called color under res, then you set the selector as the background in the layout for each item in the ListView, not on the ListView itself:

<?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="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"
    />
    
</RelativeLayout>

I'm seeing the background color change flash when I touch each item in the ListView however, they are not staying and reverting back to the original background color. This is the selector I'm using:

<?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="@android:color/transparent" />
    
    <item android:state_pressed="true" android:drawable="@color/blue" />
    
    <item android:state_selected="true" android:state_pressed="false" android:drawable="@color/blue" />

</selector>

color.xml:

<?xml version="1.0" encoding="UTF-8"?>

<resources>    
    <color name="blue">#ff33b5e5</color>        
</resources>

What an absolute pain in the ass this is. Whoever came up with this terrible system for dealing with the UI should be fired.

Solution:

Not 100% sure, but this may only work in Android 3.0+ devices. state_activated is what sets the background color.

Community
  • 1
  • 1
Kris B
  • 3,436
  • 9
  • 64
  • 106

2 Answers2

1

What you're looking for is a combination of a stateListDrawable (also known as a selector) and choiceMode.

Include in your drawables folder an xml like this one (I'm using other drawables as my backgrounds, but color works just as well):

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
        <item android:state_focused="true"
          android:drawable="@drawable/list_item_pressed" />
    <item android:state_pressed="true"
          android:drawable="@drawable/list_item_pressed" />
    <item android:state_selected="true"
          android:state_activated="true"
          android:drawable="@drawable/list_item_selected" />
    <item android:state_activated="true"
          android:drawable="@drawable/list_item_selected" />
    <item android:state_selected="true"
          android:drawable="@android:color/black" />
    <item android:drawable="@android:color/transparent" />
</selector>

and then set your listview's choiceMode to singleChoice

<ListView
  ...
  android:choiceMode="singleChoice"

This lets the OS handle your backgrounds for you.

JRaymond
  • 11,625
  • 5
  • 37
  • 40
  • Thanks for the response. I've updated my OP, trying to implement your solution, but it's not working. – Kris B Apr 14 '12 at 02:40
  • @Kris B, It's not working because it's looking for the `activated` state and you don't have an entry for that (by itself). You have it in combination with `selected`. In touch mode, there is no such thing as `selected` (or `focused`), so that state is never true. Change the state list xml line containing `activated` to `` and you should get the effect you desire. – Barak Apr 14 '12 at 04:47
  • Yea, but shouldn't using `` change the entire `ListView` to black? That's my problem, I don't think it's recognizing any of the selectors. – Kris B Apr 14 '12 at 14:38
  • @KrisB listSelector uses a different mechanism, I don't know for sure what it is, but it might correspond to state_checked and not state_selected. In any case instead of listSelector I'm usually inflating a custom ListItem for setting the background so I haven't run into what you're describing. – JRaymond Apr 14 '12 at 17:39
  • Check out my OP, I added another update. I'm getting closer, just not getting the background color to stick. – Kris B Apr 14 '12 at 19:04
  • @KrisB what platform are you running on? – JRaymond Apr 14 '12 at 19:18
  • @KrisB did you try state_checked? – JRaymond Apr 14 '12 at 20:37
  • Yep, no luck. I even removed `onListItemClick` thinking something in that was causing it not to stay, but nothing. – Kris B Apr 15 '12 at 01:57
  • @KrisB I suppose I should have known, since I usually work on honeycomb+ that this was more complicated than I thought. As referenced in ths post: http://stackoverflow.com/questions/5058291/highlight-listview-selected-row You have to have the content items of your ListView be checkable. The simplest way to do that in your case is with a CheckedTextView - http://developer.android.com/reference/android/widget/CheckedTextView.html – JRaymond Apr 15 '12 at 02:22
  • @JRaymond When I run my app in the emulator for using Android 4.0, the background color stays so this might only work in 3.0+ devices? Either way, I'm not going to worry about it too much. Thanks for your responses. – Kris B Apr 15 '12 at 15:20
0

just a simple solution is in onitemclick just rememeber the clicked position of the item and call notifydatachanged() and in getView() of your custom adapter just before retrun statement a if loop comparing like below:::

if(postion == itemclickedposition)
    converterView.setBackgroundColor(Color.GRAY);
Shankar Agarwal
  • 34,573
  • 7
  • 66
  • 64