Change background color of an item in Android ListActivity onListItemClick
Asked Answered
G

6

10

I know it sounds very simple, and there are questions about this. But none of it could solve my problem. So here we go:

I want to change background color of a list item in a ListActivity when user clicks on it, and change it back to original color when user clicks again (i.e. Select/Unselect item sort of look)

I tried using getChildAt, it works perfectly if I have all the items visible in one screen without having to scroll.

Code:

getListView().getChildAt(position).setBackgroundColor(Color.CYAN);

The problem begins when I have more items in the list and user has to scroll through them. Once background for an item is changed, The background color shows up on the newly visible items as I scroll. Also, the getChildAt(position) returns null (and hence a NullPointerException) when clicking again on the item.

Can anyone please help me with a simple code that helps me change background color of a list item?

Thanks in advance!

Gasman answered 26/9, 2012 at 21:27 Comment(1)
I think this topic will help you to do that. #2218253Haworth
C
5

Sure thing. I would do this in the getView() method of a custom ListAdapter.

MyAdapter extends SimpleAdapter {
    private ArrayList<Integer> coloredItems = new ArrayList<Integer>();

    public MyAdapter(...) {
        super(...);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v = super.getView(position, convertView, parent);

        if (coloredItems.contains(position)) {
            v.setBackgroundColor(Color.CYAN);
        } else {
            v.setBackgroundColor(Color.BLACK); //or whatever was original
        }

        return v;
    }
}

Update coloredItems when a list item is clicked.

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    if (coloredItems.contains(position)) {
        //remove position from coloredItems
        v.setBackgroundColor(Color.BLACK); //or whatever was original
    } else {
        //add position to coloredItems
        v.setBackgroundColor(Color.CYAN);
    }
}
Cyte answered 26/9, 2012 at 21:36 Comment(2)
Awesome! That worked just perfect! I had a hard time trying to figure out the solution. Your answer was very helpful. Wish I could give you two Votes up... :) Thanks again! :)Gasman
after a few hours of dead ends you showed me the right path , well done man!Trunnel
L
2

If you are dealing with ListFragment then this code will be helpful,

  @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        if (view != null) {
            getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
            getListView().setDescendantFocusability(ListView.FOCUS_AFTER_DESCENDANTS);
            catagoryValueListView=getListView();
            catagoryValueListView.setOnItemClickListener(new OnItemClickListener() {

             @Override
             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                 if (ColoredView != null)
                     ColoredView.setBackgroundColor(Color.WHITE); //original color

                 view.setBackgroundColor(Color.BLUE); //selected color
                 ColoredView = view;
                                  }
        });
    }

}
Ladonnalady answered 29/10, 2013 at 5:28 Comment(1)
Please update your answer and past your code inside code tags.Unprecedented
C
1

What I do is I create an xml file called i.e. list_background and put it in the drawable folder.

The xml looks like this:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
   <item android:drawable="@color/list_selected" android:state_pressed="true" />
   <item android:drawable="@android:color/white" />
</selector>

And in the xml code for the ListView's item I put this xml as the items background i.e.

item.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
          style="@style/Fill"
          android:background="@drawable/list_background">

     <!-- Your layout here -->
</RelativeLayout>

style=@style/Fill is only a short cut i made for android:layout_height="match_parent" and android:layout_width="match_parent

Then in onListItemCLick:

public void onListItemClick(ListView l, View v, int position, long id) {
    v.setPressed( !v.isPressed ) //Toggle between colors of the view
}
Comanchean answered 26/9, 2012 at 21:39 Comment(4)
Thanks for the help! But have two problems with this solution: 1) You can select only one item at a time, if you try to select another item the first one automatically looses it's background color. 2) If you select an item, scroll down and then scroll back up, what you see is the selected item has no background color now! :( Please help. Thanks!Gasman
Yes, you need to modify the getView method of your ListAdapter to persist that state (see my answer below). Because ListView reuses item Views, an item that appears at the top (after a scroll) may inherit traits from an item that left at the bottom unless those traits are reset in getView.Cyte
@heycosmo: What if I am not using my own ListAdapter? Because I am using a SimpleAdapter. How can I solve this?Gasman
@SurajBajaj Subclass SimpleAdapter and override getView. I'll update my answer according to this detail.Cyte
A
1

Simply you can do it like this in onListItemClick method

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);

    for (int a = 0; a < l.getChildCount(); a++) {
        l.getChildAt(a).setBackgroundColor(Color.TRANSPARENT);
    }

    ColorDrawable colorDrawable1 = new ColorDrawable(
            Color.parseColor("#A0A3A0"));
    v.setBackgroundDrawable(colorDrawable1);   

    if (position == 0) {
        Intent i = new Intent(MainActivity.this, NewActivity.class);

        startActivity(i);
    }

}
Asti answered 18/12, 2014 at 10:17 Comment(0)
B
0

this is how I did it:

create a global variable View ColoredView; then when you setOnItemClickListener for your ListView, do this:

MenuList.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if (ColoredView != null)
                    ColoredView.setBackgroundColor(Color.WHITE); //original color

                view.setBackgroundColor(Color.BLUE); //selected color
                ColoredView = view;
            }
        });

it's the simplest way in my opinion.

Bakst answered 2/4, 2013 at 5:30 Comment(0)
E
0

Thanks heycosmo. your solution solved my problem.

Have no clue why we should set background in 2 places.

1. Adapter's getView()

@Override
public View getView(int position, View convertView, ViewGroup parent) {
     ....
     ....
     ....
        if(arrayBools[position]) {
            view.setBackgroundColor(Common.colorBkgroundSelected);
        }
        else{
            view.setBackgroundColor(Common.colorBkgroundNormal);            
        } 
     ....
     ....
     ....
}

2. ListActivity's onListItemClick().

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
      super.onListItemClick(l, v, position, id);       
      arrayBools[position] = ( arrayBools[position] ? false : true );

     if(arrayBools[position]) {
         v.setBackgroundColor(colorBkgroundSelected);
     }
     else{
        v.setBackgroundColor(colorBkgroundNormal);          
     }    
}
Edging answered 20/12, 2013 at 10:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.