selected item on custom listview with contextual action bar

32,008

Solution 1

I've only ever tested this in CHOICE_MODE_SINGLE, but in that situation it works by doing the following.

  • When you select a list item, in code, call "setItemChecked(position, checked)" method (on the ListView instance) for that item in the list.

  • Add this to the XML for individual ListView items:
    android:background="?android:attr/activatedBackgroundIndicator"

Solution 2

Just create a a drawable called custom_background on the way:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/highlight" android:state_activated="true"/>
    <item android:drawable="@color/normal"/>
</selector>

and set as background on your parent layout:

android:background="@drawable/custom_background"
Share:
32,008

Related videos on Youtube

domi
Author by

domi

Updated on July 09, 2022

Comments

  • domi
    domi almost 2 years

    I recently started using android actionbars and contextual action bars (CAB).

    I have just one activity which is a ListActivity. Basically I use the following code snipped to "activate" the CAB:

    ListView listView = getListView();
    listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
    listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
    
        @Override
        public void onItemCheckedStateChanged(ActionMode mode, int position,
                                          long id, boolean checked) {
            // Here you can do something when items are selected/de-selected,
            // such as update the title in the CAB
        }
    
        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            // Respond to clicks on the actions in the CAB
            switch (item.getItemId()) {
                case R.id.menu_delete:
                    deleteSelectedItems();
                    mode.finish(); // Action picked, so close the CAB
                    return true;
                default:
                    return false;
            }
        }
    
        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            // Inflate the menu for the CAB
            MenuInflater inflater = mode.getMenuInflater();
            inflater.inflate(R.menu.context, menu);
            return true;
        }
    
        @Override
        public void onDestroyActionMode(ActionMode mode) {
            // Here you can make any necessary updates to the activity when
            // the CAB is removed. By default, selected items are deselected/unchecked.
        }
    
        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            // Here you can perform updates to the CAB due to
            // an invalidate() request
            return false;
        }
    });
    

    The layout of the list:

    <ImageView
        android:id="@+id/message_on_clipboard_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:minWidth="30dp"
        android:padding="7sp"
        android:src="@android:drawable/presence_online" >
    </ImageView>
    
    <LinearLayout
        android:id="@+id/linearLayout2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/listitem_background"
        android:orientation="vertical" >
    
        <TextView
            android:id="@+id/message"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginRight="5sp"
            android:fadingEdge="horizontal"
            android:singleLine="true"
            android:text="TextView"
            android:textAppearance="?android:attr/textAppearanceLarge" >
        </TextView>
    
        <LinearLayout
            android:id="@+id/linearLayout1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/listitem_background"
            android:orientation="horizontal" >
    
            <TextView
                android:id="@+id/message_length"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginRight="5sp"
                android:text="@string/message_length"
                android:textAppearance="?android:attr/textAppearanceSmall" >
            </TextView>
    
            <TextView
                android:id="@+id/message_count"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginRight="5sp"
                android:text="TextView"
                android:textAppearance="?android:attr/textAppearanceSmall" >
            </TextView>
    
            <TextView
                android:id="@+id/date_label"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginRight="5sp"
                android:text="@string/date_label" >
            </TextView>
    
            <TextView
                android:id="@+id/date_message"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="TextView" >
            </TextView>
        </LinearLayout>
    </LinearLayout>
    

    And within main.xml:

    <ListView
        android:id="@+android:id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
    >
    </ListView>
    

    Now if I do a long click on a list item the CAB shows up as expected:

    cab

    I use a MultiChoiceModeListener but unfortunately the selected list items do not change the background like in the example here (light blue background after an item is selected):

    enter image description here

    Do I have to use a custom selector? Or is there a standard procedure how android does handle this and I just need to make my LinearLayouts transparent? I also tried the following but with no success:

    ListView item background via custom selector

    It would be great If somebody could point me in the right direction. Please let me know if you need more application code or xml files.

  • domi
    domi about 12 years
    I get a StackOverflowError if I do the following within onItemCheckedStateChanged(): listView.setItemChecked(position, checked);
  • domi
    domi about 12 years
    nvm. it works just with: android:background="?android:attr/activatedBackgroundIndicat‌​or" thank you so much!
  • Konsumierer
    Konsumierer almost 12 years
    As an addition to domi´s comment: if you want to customize the look of selected rows you can do so by using your own implementation of the row´s layout, as it is described in this tutorial: marvinlabs.com/2010/10/custom-listview-ability-check-items
  • Takeshi Kaga
    Takeshi Kaga over 11 years
    The call to setItemChecked will result in StackOverflowError because calling setItemChecked in onItemCheckedStateChanged will be just calling each other infinitely.
  • jrharshath
    jrharshath about 11 years
    Konsumierer's link is no longer valid.. new link: blog.marvinlabs.com/2010/10/29/…
  • crdx
    crdx about 11 years
    For lists listChoiceBackgroundIndicator is a better choice.
  • Michael Kariv
    Michael Kariv about 10 years
    Sure calling setItemChecked() inside onItemCheckedStateChanged will result in StackOverflow - because onItemCheckedStateChanged is called when one changes the item check status - so you create an endless loop
  • Admin
    Admin about 10 years
    I am uunable to call this setItemChecked in my adapter class? How to call it and which parameter to send.
  • Ivan Morgillo
    Ivan Morgillo over 9 years
    Perfect! I created the selector and applied it as grid view item background. Thanks.
  • jitain sharma
    jitain sharma over 9 years
    To @domi, by setting this listView.setItemChecked(position, checked);, your invoking the onItemCheckedStateChanged method again and again which results to end-less calls to the method and finally results to StackOverflowError. Hope it will resolve your query.
  • domi
    domi over 9 years
    @jitainsharma yeah I know! already pointed out by Takeshi Kaga.