4

I have android app with list view with choice mode set to multiple choice modal.

Items on this list are defined as relative layouts.

How can I change the background of items when they are selected?

Item xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    android:checkable="true"
    android:background="@drawable/my_item_background"

My item background xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:drawable="@color/mycolor1" android:state_selected="true"/>
    <item android:drawable="@color/mycolor2" android:state_checked="true"/>
    <item android:drawable="@android:color/black"/>
</selector>

Item's background is always black.

Ari
  • 3,101
  • 2
  • 27
  • 49

2 Answers2

9

You can use a selector

In your Relative Layout Add

  android:background=@drawable/bkg"

Then in drawable folder have bk.xml

<?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>

pressed.xml

<?xml version="1.0" encoding="UTF-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android"> 
    <solid android:color="#FF1A47"/>    // change the colors to meet your requirement
    <stroke android:width="3dp"
            android:color="#0FECFF"/>
    <padding android:left="5dp"
             android:top="5dp"
             android:right="5dp"
             android:bottom="5dp"/> 
    <corners android:bottomRightRadius="7dp" // for rounded corner remove this if not required
             android:bottomLeftRadius="7dp" 
             android:topLeftRadius="7dp"
             android:topRightRadius="7dp"/> 
</shape>

normal.xml

<?xml version="1.0" encoding="UTF-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android"> 
    <solid android:color="#FFFFFF"/>    
    <stroke android:width="3dp"
            android:color="#0FECFF" />

    <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>

Edit:

The sample can be found @

android-sdk-linux/samples/android-17/ApiDemos/src/com/example/android/apis/view/List16

From your comments and discussion i assume this is what you want.

public class MainActivity extends ListActivity {
    String[] GENRES = new String[] {
            "Action", "Adventure", "Animation", "Children", "Comedy",
        "Documentary", "Drama",
            "Foreign", "History", "Independent", "Romance", "Sci-Fi",
        "Television", "Thriller"
        };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ListView lv = getListView();
        lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
        lv.setMultiChoiceModeListener(new ModeCallback());
        setListAdapter(new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_activated_1, GENRES));
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        getActionBar().setSubtitle("Long press to start selection");
    }

    private class ModeCallback implements ListView.MultiChoiceModeListener {

        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            MenuInflater inflater = getMenuInflater();
            inflater.inflate(R.menu.list_select_menu, menu);
            mode.setTitle("Select Items");
            return true;
        }

        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return true;
        }

        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            switch (item.getItemId()) {
            case R.id.share:
                Toast.makeText(MainActivity.this, "Shared " + getListView().getCheckedItemCount() +
                        " items", Toast.LENGTH_SHORT).show();
                mode.finish();
                break;
            default:
                Toast.makeText(MainActivity.this, "Clicked " + item.getTitle(),
                        Toast.LENGTH_SHORT).show();
                break;
            }
            return true;
        }

        public void onDestroyActionMode(ActionMode mode) {
        }

        public void onItemCheckedStateChanged(ActionMode mode,
                int position, long id, boolean checked) {
            final int checkedCount = getListView().getCheckedItemCount();
            switch (checkedCount) {
                case 0:
                    mode.setSubtitle(null);
                    break;
                case 1:
                    mode.setSubtitle("One item selected");
                    break;
                default:
                    mode.setSubtitle("" + checkedCount + " items selected");
                    break;
            }
        }

    }
}

list_select_menu.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/share"
          android:title="share"
          android:icon="@android:drawable/ic_menu_share"
          android:showAsAction="always" />
</menu>

Snap shot

enter image description here

Raghunandan
  • 132,755
  • 26
  • 225
  • 256
  • When I set bg for state pressed it is only active when I press an item. Item is selected but bg is changed back to normal. – Ari Jul 17 '13 at 11:34
  • yes it should work that way right when you press users should know they pressed and when they lift it should return to normal. just like how buttons work. – Raghunandan Jul 17 '13 at 11:35
  • But it is multiple choice. So they can see that they selected X items, but they can't see which one. – Ari Jul 17 '13 at 11:37
  • that's why you have check box so why do you need to change the background in that case. also you would scroll your listview. – Raghunandan Jul 17 '13 at 11:39
  • I don't have checkboxes. I want bg to show if item is checked or not – Ari Jul 17 '13 at 11:41
  • what do you mean by checked . better to use check boxes which allows users to know what items are selected. – Raghunandan Jul 17 '13 at 11:42
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/33629/discussion-between-ari-and-raghunandan) – Ari Jul 17 '13 at 11:43
  • @Ari check this http://stackoverflow.com/questions/14737519/how-can-you-implement-multi-selection-and-contextual-actionmode-in-actionbarsher/14737520#14737520. – Raghunandan Jul 17 '13 at 12:12
  • @Ari after some research i searched the api post. i will post the same now by editing. – Raghunandan Jul 17 '13 at 13:36
0

You can use a drawable selector for this. Create a new xml in the res/drawable folder e.g. list_item_background.xml and use this to select 2 different drawables for default state and selected state:

list_item_background.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/listitem_selected" android:state_selected="true" />
    <item android:drawable="@drawable/listitem_normal" />
</selector>
Xaver Kapeller
  • 49,491
  • 11
  • 98
  • 86