Changing background color of ListView items on Android

AndroidListviewColors

Android Problem Overview


How can I change background color of ListView items on a per-item basis. When I use android:backgroundColor in the ListView item layout I can achieve this, however the list selector is no longer visible. I can make the selector visible again by setting drawSelectorOnTop to true but then the selector overlays the whole item.

Any ideas how to change those background colors and keep the selector?

PS I would rather not change the selector itself.

EDIT: Authors of GMail application have managed to achieve exactly this so it's definitely possible.

Android Solutions


Solution 1 - Android

You have to create a different state drawable for each color you want to use.

For example: list_selector_read.xml and list_selector_unread.xml.

All you need to do is set everything to transparent except the android:state_window_focused="false" item.

Then when you are drawing your list you call setBackgroundResource(R.drawable.list_selector_unread/read) for each row.

You don't set a listSelector on the ListView at all. That will maintain the default selector for your particular flavor of Android.

Solution 2 - Android

This is a modification based on the above code, a simplest code:

private static int save = -1;

public void onListItemClick(ListView parent, View v, int position, long id) { 
	  		
	parent.getChildAt(position).setBackgroundColor(Color.BLUE);
	
	if (save != -1 && save != position){
		parent.getChildAt(save).setBackgroundColor(Color.BLACK);
	}
	
	save = position;  		  		
	
}

I hope you find it useful

greetings!

Solution 3 - Android

Ok, I got it to work like this:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="false" android:drawable="@color/BackgroundColor" />
    <item android:drawable="@color/transparent" />
</selector>

YMMV!

Solution 4 - Android

No one seemed to provide any examples of doing this solely using an adapter, so I thought I would post my code snippet for displaying ListViews where the "curSelected" item has a different background:

final ListView lv = (ListView)findViewById(R.id.lv);
lv.setAdapter(new BaseAdapter()
{
    public View getView(int position, View convertView, ViewGroup parent)
    {
        if (convertView == null)
        {
            convertView = new TextView(ListHighlightTestActivity.this);
            convertView.setPadding(10, 10, 10, 10);
            ((TextView)convertView).setTextColor(Color.WHITE);
        }

        convertView.setBackgroundColor((position == curSelected) ? 
            Color.argb(0x80, 0x20, 0xa0, 0x40) : Color.argb(0, 0, 0, 0));
        ((TextView)convertView).setText((String)getItem(position));
			
        return convertView;
    }
		
    public long getItemId(int position)
    {
        return position;
    }

    public Object getItem(int position)
    {
        return "item " + position;
    }

    public int getCount()
    {
        return 20;
    }
});

This has always been a helpful approach for me for when appearance of list items needs to change dynamically.

Solution 5 - Android

mAgendaListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//view.setBackgroundColor(Color.RED);
             
for(int i=0; i<parent.getChildCount(); i++)
{
     if(i == position)
     {
               parent.getChildAt(i).setBackgroundColor(Color.BLUE);
     }
     else
     {
               parent.getChildAt(i).setBackgroundColor(Color.BLACK);
     }
              
 }

Solution 6 - Android

From the source code of Android's 2.2 Email App:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_window_focused="false" android:state_selected="true"
        android:drawable="@android:color/transparent" />
    <item android:state_selected="true"
        android:drawable="@android:color/transparent" />
    <item android:state_pressed="true" android:state_selected="false"
        android:drawable="@android:color/transparent" />
    <item android:state_selected="false"
        android:drawable="@color/message_item_read" />
</selector>

Nothing more to say...

Solution 7 - Android

the easiest way is this. Inside your ListArrayAdapter just do this

if(your condition here) rowView.setBackgroundColor(Color.parseColor("#20FFFFFF"));

don't over complicate

Solution 8 - Android

Did you mean to change the background color of the custom listitems when you click on it?

If so:

You just add the following code to your listview layout in xml.


> android:drawSelectorOnTop="true" > android:listSelector="@android:drawable/list_selector_background"


The list selector here uses default selector which has a dark grey color. You can make your own drawable and assign it to the list selector as above.

Hope this is what you wanted.

Solution 9 - Android

Simple code to change all in layout of item (custom listview extends baseadapter):

lv.setOnItemClickListener(new OnItemClickListener() {

		@Override
		public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
				long arg3) {
			
			RelativeLayout layout=(RelativeLayout) arg1.findViewById(R.id.rel_cell_left);
			layout.setBackgroundColor(Color.YELLOW);

			
			
		}
	});

Solution 10 - Android

Following way very slowly in the running

mAgendaListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//view.setBackgroundColor(Color.RED);

for(int i=0; i<parent.getChildCount(); i++)
{
     if(i == position)
     {
               parent.getChildAt(i).setBackgroundColor(Color.BLUE);
     }
     else
     {
               parent.getChildAt(i).setBackgroundColor(Color.BLACK);
     }

 }

Replaced by the following

int pos = 0;
int save = -1;
	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position,
			long id) {
			//Always set the item clicked blue background
			view.setBackgroundColor(Color.BLUE);
			
			if (pos == 0) {
				if (save != -1) {
					parent.getChildAt(save).setBackgroundColor(Color.BLACK);
				}
				save = position;
				pos++;
				Log.d("Pos = 0", "Running");

			} else {
				parent.getChildAt(save).setBackgroundColor(Color.BLACK);
				save = position;
				pos = 0;
				Log.d("Pos # 0", "Running");
			}

Solution 11 - Android

By changing a code of Francisco Cabezas, I got the following:

private int selectedRow = -1;

...

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    parent.getChildAt(position).setBackgroundResource(R.color.orange);
    if (selectedRow != -1 && selectedRow != position) {
        parent.getChildAt(selectedRow).setBackgroundResource(R.color.black);
    }
    selectedRow = position;

Solution 12 - Android

Take a look at List14 example. In getView() you can call convertView.setBackgroundDrawable() for each entry. You could have a class member counter to decide which background to call it with to get alternating backgrounds, for example.

Solution 13 - Android

In the list view you can add android:listselector=color name that you want.

this work fine in my app.

Solution 14 - Android

The best tutorial on this can be found here.

Key sections:

  1. Surely call view.setSelected(true) in onItemClick, otherwise the you can't see the selected item background
  2. Preserve the order of states in your selector otherwise you'll see unpredictable behavior in background colors (state_selected followed by state_pressed)

Solution 15 - Android

You can do This.

 final List<String> fruits_list = new ArrayList<String>(Arrays.asList(fruits));

    // Create an ArrayAdapter from List
    final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>
            (this, android.R.layout.simple_list_item_1, fruits_list){
        @Override
        public View getView(int position, View convertView, ViewGroup parent){
            // Get the current item from ListView
            View view = super.getView(position,convertView,parent);
            if(position %2 == 1)
            {
                // Set a background color for ListView regular row/item
                view.setBackgroundColor(Color.parseColor("#FFB6B546"));
            }
            else
            {
                // Set the background color for alternate row/item
                view.setBackgroundColor(Color.parseColor("#FFCCCB4C"));
            }
            return view;
        }
    };

    // DataBind ListView with items from ArrayAdapter
    lv.setAdapter(arrayAdapter);
}

}

Solution 16 - Android

If the setBackgroundColor is added for onItemClick event, it will not work unless you can put it after the click event.

Try to add debug code in the adapter's getView method, you will find that getView will be called again whenever you click on the screen. So, after you set the background color, the system will redraw the screen with original setting. Don't know why it waste resource to rebuild the screen whenever it's being click, there already have other way that we can notify the system to redraw the screen when needed.

Maybe you can add some control flag to determine the background color for individual row, then modify the getView method to set the color according to this control flag. So, the background color will be changed when it redraw the screen.

I'm also looking for an official solution on it.

Solution 17 - Android

I tried all answers above .. none worked for me .. this is what worked eventually and is used in my application .. it will provide read/unread list items colors while maintaining listselector styles for both states :

<ListView
                android:id="@+id/list"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:listSelector="@drawable/selectable_item_background_general"
                android:drawSelectorOnTop="true"
                android:fadingEdge="none"
                android:scrollbarStyle="outsideOverlay"
                android:choiceMode="singleChoice" />

selectable_item_background_general.xml :

<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_mediumAnimTime">
	<item android:state_pressed="false" android:state_focused="true" android:drawable="@drawable/bg_item_selected_drawable" />
	<item android:state_pressed="true" android:drawable="@drawable/bg_item_selected_drawable" />
	<item android:drawable="@android:color/transparent" />
</selector>

bg_item_selected_drawable.xml :

<shape xmlns:android="http://schemas.android.com/apk/res/android">
	<solid android:color="#12000000" />
</shape>

notification_list_itemlayout.xml :

<RelativeLayout 
			xmlns:android="http://schemas.android.com/apk/res/android"
    		android:id="@+id/rowItemContainer"
		    android:layout_width="fill_parent"
		    android:layout_height="wrap_content">

	<RelativeLayout 
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    android:padding="8dp"
	    android:paddingLeft="16dp"
	    android:paddingStart="16dp"
	    android:paddingRight="16dp"
	    android:paddingEnd="16dp">

		    <ImageView
		        android:id="@+id/imgViewIcon"
		        android:layout_width="60dp"
		        android:layout_height="60dp"
		        android:src="@drawable/cura_logo_symbol_small"
		        android:layout_alignParentLeft="true"
		        android:layout_alignParentStart="true"
		        android:layout_marginRight="8dp"
		        android:layout_marginEnd="8dp" />
		    <TextView
		        android:id="@+id/tvNotificationText"
		        android:layout_width="wrap_content"
		        android:layout_height="wrap_content"
		        android:layout_alignTop="@+id/imgViewIcon"
		        android:layout_toRightOf="@+id/imgViewIcon"
		        android:layout_toEndOf="@+id/imgViewIcon"
		        android:textSize="@dimen/subtitle"
		        android:textStyle="normal" />
		    <TextView
		        android:id="@+id/tvNotificationTime"
		        android:layout_width="fill_parent"
		        android:layout_height="wrap_content"
		        android:layout_marginTop="1dip"
		        android:layout_below="@+id/tvNotificationText"
		        android:layout_toRightOf="@+id/imgViewIcon"
		        android:layout_toEndOf="@+id/imgViewIcon"
		        android:textSize="@dimen/subtitle" />
        </RelativeLayout>
</RelativeLayout>

Finally, in your adapter :

if (!Model.Read)
    rowItemContainer.SetBackgroundColor (Android.Graphics.Color.ParseColor ("#FFFDD0")); // unread color
else
    rowItemContainer.SetBackgroundColor (Android.Graphics.Color.White); // read color

Solution 18 - Android

That's what I used (Kotlin):

if(blablabla == "whatever") {
    view.setBackgroundColor(getColor(context, R.color.teal_200))
} else {
    view.setBackgroundColor(getColor(context, R.color.teal_700))
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMarek St&#243;jView Question on Stackoverflow
Solution 1 - AndroidHawkeeView Answer on Stackoverflow
Solution 2 - AndroidFrancisco CabezasView Answer on Stackoverflow
Solution 3 - AndroidAdamView Answer on Stackoverflow
Solution 4 - AndroidubzackView Answer on Stackoverflow
Solution 5 - AndroidMbollandView Answer on Stackoverflow
Solution 6 - AndroidThePCWizardView Answer on Stackoverflow
Solution 7 - AndroidOWADVLView Answer on Stackoverflow
Solution 8 - AndroidPrasadWView Answer on Stackoverflow
Solution 9 - AndroidNguyễn Anh QuếView Answer on Stackoverflow
Solution 10 - AndroidPrDoHungView Answer on Stackoverflow
Solution 11 - AndroidCoolMindView Answer on Stackoverflow
Solution 12 - AndroidHeikki ToivonenView Answer on Stackoverflow
Solution 13 - AndroidShivani KhandelwalView Answer on Stackoverflow
Solution 14 - AndroidMohsen AfshinView Answer on Stackoverflow
Solution 15 - AndroidFouziya ParveenView Answer on Stackoverflow
Solution 16 - AndroidSuper169View Answer on Stackoverflow
Solution 17 - AndroidMohammad ZekrallahView Answer on Stackoverflow
Solution 18 - AndroidLaurentView Answer on Stackoverflow