2

I have a ListView and I would like to change the color of the selected item in the list. I can change the color of the selected item below, but how do I revert (or change) the color of all the other items back to their original color?

@Override
    public void onListItemClick(ListView parent, View v, int position, long id) 
        v.setBackgroundColor(Color.CYAN);
    }

I tried changing the color of the parent but it doesn't change the color of the items:

 @Override
    public void onListItemClick(ListView parent, View v, int position, long id) 
        parent.setBackgroundColor(Color.WHITE);
        v.setBackgroundColor(Color.CYAN);
    }

ListView:

        <ListView
        android:id="@id/android:list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:choiceMode="singleChoice"
        android:clickable="true"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:drawSelectorOnTop="false" />

Each item is:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/contacts_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<LinearLayout android:id="@+id/linear"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/username"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:text=""/>

    <TextView
        android:id="@+id/lastname"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:layout_marginLeft="3sp"
        android:text=""/>

    <TextView
        android:id="@+id/firstname"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:layout_marginLeft="3sp"
        android:text=""/>

    <TextView
        android:id="@+id/sipExt"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="15sp"
        android:textColor="#59696E"
        android:gravity="right"
        android:layout_marginRight="9dp"
        android:textStyle="italic"
        android:text=""/>

</LinearLayout>

    <TextView
    android:id="@+id/alias"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="14sp"
    android:textColor="#a69d86"
    android:textStyle="italic"
    android:layout_below="@id/linear"
    android:text=""/>

ono
  • 2,984
  • 9
  • 43
  • 85

4 Answers4

4

There proper way to do this is to define a custom Selector and set the color (Drawable) and set the colors as you want them to be in each state. See this link for details:

Can't add custom selector to ListView

and here:

Android ListView selected item stay highlighted

-- there are plenty of other posts on SO regarding this as well.

If you want to keep your current design you can try something like this:

 View lastTouchedView;

 @Override
 public void onListItemClick(ListView parent, View v, int position, long id) 
    lastTouchedView.setBackgroundColor(Color.WHITE);
    v.setBackgroundColor(Color.CYAN);
    lastTouchedView = v;
 }
Community
  • 1
  • 1
Scott
  • 1,652
  • 1
  • 13
  • 10
  • I have highligthting repeating. With about 339 items, it looks like very 12th is highlighted. Any clues why? – ono Jul 24 '13 at 17:30
  • to clarify, you are saying you have a list with 339 items and every 12th item is staying highlighted? If this is the please tell me how many items fit on your screen at any time. – Scott Jul 24 '13 at 17:54
  • It's very strange. If the first one is highlighted, I scroll the screen until the 12th is shown highlighted. When I scroll back to the first one, it is occasionally unselected and the 2nd or 3rd are highlighted. 12 fit on the screen at once. The 14th is highlighted if the first is highlighted. – ono Jul 24 '13 at 18:25
  • are you using a custom adapter with an overridden `getView(...)` method? – Scott Jul 24 '13 at 18:39
  • There's an onCreateView, no getView – ono Jul 24 '13 at 18:41
  • Is this layout in an activity or a fragment, and what is the parent class of the activity or fragment class? Im thinking you are running into an issue with view recycling - an optimization that android does with list views - google it to learn more. In the mean time, more code would be helpful – Scott Jul 24 '13 at 18:46
  • It definitely looks like view recylcing. Is there anyway to change the layout by position instead of view? The item positions are consistent. – ono Jul 24 '13 at 18:49
  • 1
    Yes, there is. You set up xml files like in the links I have provided which are the same as @Raghunandan answer. Then, in `onListItemClick(...)` you call 'parent.setSelected(position)' or something like this. – Scott Jul 24 '13 at 19:12
3

Use a selector.

To the required view in custom layout xml

 android:background="@drawable/bkg.xml"

bkg.xml in drawable folder.

<?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/pressed" />
    <item  android:state_focused="false" 
        android:drawable="@drawable/normal" />
</selector>

Customize the below according to your requirements

pressed.xml in 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="#ff33ffff" />
 <padding android:left="5dp"
         android:top="5dp"
         android:right="5dp"
         android:bottom="5dp"/> 
 <corners android:bottomRightRadius="7dp"
         android:bottomLeftRadius="7dp" 
         android:topLeftRadius="7dp"
         android:topRightRadius="7dp"/> 
 </shape>

normal.xml in drawable folder

  <?xml version="1.0" encoding="UTF-8"?> 
  <shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">  // rectangle shape
  <solid android:color="@android:color/transparent"/>   
  <stroke android:width="3dp"
        android:color="#0FECFF" /> 
  <padding android:left="5dp"
         android:top="5dp"
         android:right="5dp"
         android:bottom="5dp"/> 
  <corners android:bottomRightRadius="7dp" // rounded corner
         android:bottomLeftRadius="7dp" 
         android:topLeftRadius="7dp"
         android:topRightRadius="7dp"/> 
  </shape>  
Raghunandan
  • 132,755
  • 26
  • 225
  • 256
  • Does `android:background="@drawable/bkg.xml"` go with the ListView layout? – ono Jul 24 '13 at 17:31
  • @ono well i see you have already accepted the answer. seems problem solved. – Raghunandan Jul 24 '13 at 17:33
  • @Ono you need to have `android:background="@drawable/bkg.xml"` fro your custom layout to be inflated for each row. For the last xml in your question. You cannot accept two answers. If the other answer helps go ahead mark that as accepted. – Raghunandan Jul 24 '13 at 17:36
3

You may try the following to retrieve all items from the parent containing the views and then set the background color of all the items

public void onListItemClick(ListView parent, View v, int position, long id){

            //Set background of all items to white
            for (int i=0;i<parent.getChildCount();i++){
                parent.getChildAt(i).setBackgroundColor(Color.WHITE);
            }

            v.setBackgroundColor(Color.CYAN);
}
0

You just need to use CustomAdapter for this and inside it you need to declare a global int variable which contains the selected Position index and inside getView method of the adapter just check match selected Position with position value of getView method and change the row view background accordingly.

EEJ
  • 678
  • 5
  • 12