Search code examples
androidlistviewadapterhighlightonlongclicklistener

How to highlight a ListView item using OnLongClickListener from custom Adapter class in Android


Here's what I want to do:

In my main Activity I have a ListView with a custom Adapter because my ListView item should contain a TextView AND a CheckBox. When I do a long press on an item, I wanna use a contextual action mode in the ActionBar and HIGHLIGHT the selected ListView item.

Here's what I did:

I followed this Tutorial for the custom Adapter and this Tutorial for the ActionMode. Both is working fine. I'm able to interact with my database underlying my adapter and ListView. I should mention that I implemented everything for the ActionMode in my custom adapter class.

Here's what is NOT working:

I can't figure out how to highlight the selected ListView item although I'm able to delete the database entry corresponding to the content of the TextView in the ListView item.


Solution

  • I finally managed to find a solution myself. I took a few different steps:

    Code-related steps:

    1. I moved everything ActionMode related code from my adapter class to my activity class. Before that I triggered the action mode by using an OnLongClickListener on my TextView in my ListView item because at that point I didn't know how to make the TextView's text available for the ActionMode (I want to be able to delete it by clicking an icon in the ActionBar). When you use a CLickListener on one of the ListView items it kinda "blocks" the OnClickListener of the ListView item you set in your Activity. Don't do that!!!

    2. I set an OnItemLongClickListener to my ListView in my Activity. From there I trigger the ActionMode AND save the text from the item's TextView like this (itemNames is a List<String> set to my adapter, deleteString is a class attribute of my Activity):

      deleteString = itemNames.get(_postion);

    But these steps were only to get my code working as it is supposed to due to the changes I had to make via XML.

    XML-related steps:

    1. I had to remove the background attribute from my ListView item main layout
    2. I had to add the following attributes to my outer row layout: android:clickable="true" and android:longClickable="true" (maybe longClickable is already enough, just to be sure ;-) )
    3. I had to create an own selector drawable and set it as background to my ListView item layout: android:background="@drawable/my_selector"

    This way I achieved the following:

    • I have a ListView in my Activity with a custom layout (TextView + CheckBox) and a custom adapter
    • I can use an OnCheckedChangeListener on the CheckBox
    • I can activate ActionMode by doing a long click on my ListView item AND reach the TextView's content for further processes
    • I get the default holo_blue_light background highlight on my ListView item when I click on it (I use Holo Theme Light with Dark Action Bar for my App)

    The only thing that I didn't get to work via XML was to keep my ListView item highlighted while the ActionMode was active, so I did that by doing this

    _view.setBackgroundResource(android.R.color.holo_blue_dark);
    

    in the OnItemLongClickListener of my ListView in my Activity class (don't forget to redraw or refresh your ListView in onDestroyActionMode(ActionMode _mode) of your ActionMode.Callback)

    Voilà! I hope this might help some of you! Took me a few days and LOTS of research.

    Here my code examples for my ListView item layout and my selector layout:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/my_selector"
        android:clickable="true"
        android:longClickable="true" >
    
        <CheckBox
            android:id="@+id/checkBox"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="6dp" >
        </CheckBox>
    
        <TextView
            android:id="@+id/shoppingListItemName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_marginLeft="10dp"
            android:layout_toLeftOf="@id/checkBox"
            android:gravity="center_vertical"
            android:minHeight="?android:attr/listPreferredItemHeightSmall"
            android:textAppearance="?android:attr/textAppearanceListItemSmall"
            android:textIsSelectable="true" >
        </TextView>
    
    </RelativeLayout>
    

    My selector:

    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    
        <item android:state_pressed="true">
            <layer-list>
                <item>
                    <shape android:shape="rectangle">
                        <solid android:color="@android:color/holo_blue_light" />
                    </shape>
                </item>
            </layer-list>
        </item>
        <item>
            <color android:color="#00000000" />
        </item>
    
    </selector>