28

As seen in the tablet version of gmail and google talk I am trying to show the current selection in a listview. I know this is not standard practice and should be avoided when necessary.in my program the listview is alway on the screen and the item clicked shows a new fragment to the right (similar to gmail and google talk).

To avoid the user from guessing what item has been selected I would like to show the current selection, I tried creating a selector but after it is clicked it changes back to the normal background.

how can I achieve this?

this is my selector xml

<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="@drawable/list_item_bg2" android:state_pressed="false" android:state_selected="false"
    android:state_focused="false"/>
<item android:drawable="@drawable/list_item_selected_bg2" android:state_pressed="true"/>
<item android:drawable="@drawable/list_item_selected_bg2" android:state_pressed="false" android:state_focused="false"
    android:state_selected="true" android:state_checked="false"/>
<item android:drawable="@drawable/list_item_selected_bg2" android:state_pressed="false" android:state_focused="true"
    android:state_selected="false"/>
<item android:drawable="@drawable/list_item_selected_bg2" android:state_pressed="false" android:state_focused="false"
    android:state_selected="false" android:state_checked="true"/>
<item android:drawable="@drawable/list_item_selected_bg2" android:state_pressed="true" android:state_focused="true"
    android:state_selected="true" android:state_checked="true"/>
<item android:drawable="@drawable/list_item_selected_bg2" android:state_pressed="true"/>



</selector> 
tyczj
  • 71,600
  • 54
  • 194
  • 296

4 Answers4

73

What Gmail and similar apps use is the activated state, with an appropriate row layout. See:

In a nutshell, you:

  • Use a row layout with an activated background (e.g., android.R.layout.simple_list_item_activated_1)
  • Use setChoiceMode(ListView.CHOICE_MODE_SINGLE) on your ListView
  • "Check" the row that should be activated using setItemChecked() on your ListView to enable the "activated" state and have the persistent highlight
Community
  • 1
  • 1
CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 1
    excellent worked just as i wanted plus explanation if i need to change background color! – tyczj Mar 16 '12 at 02:56
  • Very helpful as I was trying to highlight my textviews when selected, but duplicate highlights were happening. Your explanation simply solved my issue and I no more need to make my child views as setSelected(true). Thanks – abhy Feb 18 '13 at 18:14
  • 1
    @Pinch: It's not supposed to work on Android 2.x. The `activated` concept was not introduced until Android 3.0. Since there are no Android 2.x tablets of significance, you do not need `activated` on Android 2.x, and the first link in the answer shows how to set it up to only use `activated` on Android 3.0+. – CommonsWare Aug 03 '13 at 18:05
  • 1
    @Pinch and others. You might try googling for workaaorund that uses state_checked. It is a bit more work though. You have to implement Checkable interface in your views and then you have to write correct selectors regarding the state_checked. – Anderson Sep 17 '13 at 11:07
  • In case anyone else is wondering, this works totally fine with CHOICE_MODE_MULTIPLE_MODAL as well. – davidtbernal Jan 29 '15 at 22:45
  • 2
    If anyone was wondering, this works for custom row layouts as well. All you have to do is add `android:background="?android:attr/activatedBackgroundIndicator"` to your listrow layout. – Kitalda Jun 01 '15 at 10:31
9

Your other option is to set the background of your custom list item to android:background="?android:attr/activatedBackgroundIndicator"

Jörg
  • 2,441
  • 1
  • 20
  • 18
8

If you use a custom layout for each row:

  1. create a selector with android:state_activated="true"
  2. apply it as the background of the custom layout.

an example of the selector drawable:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
 android:exitFadeDuration="@android:integer/config_shortAnimTime">
<item android:state_activated="true" android:drawable="@color/android_green" />
<item android:drawable="@android:color/transparent" />
</selector>
Raneez Ahmed
  • 3,808
  • 3
  • 35
  • 58
  • This worked for me whereas other method didn't! Thanks! From the code: listview.setChoiceMode(ListView.CHOICE_MODE_SINGLE); listview.setItemChecked(3,true); listview.setSelection(3); Here the "3" is the index of item to be selected. setItemChecked applies the drawable color background and setSelection makes the list automatically scroll to that item. – sudoExclaimationExclaimation Apr 30 '15 at 02:14
0

What worked for me

  1. override the global ListView Style in your theme

    <item name="android:listViewStyle">@style/MyListView</item>

  2. define your style

    <style name="MyListView" parent="@android:style/Widget.ListView"> <item name="android:listSelector">@drawable/listview_background_selector</item> </style>

  3. define the selector listview_background_selector.xml

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

  4. set the background of your listview-item-layout

    android:background="?android:attr/activatedBackgroundIndicator"

wutzebaer
  • 14,365
  • 19
  • 99
  • 170