Android ListView: Make Selection Stay
15 Jun 2012This post was imported from blogspot.
The behavior of Android's ListView is surprising: when the user clicks an item, it doesn't stay selected! It looks selected for a brief instant and then fades away.Apparently the "disappearing selection" is by design; it's something called "touch mode". I read through that document and still I have no idea why they thought it was a good idea. My guess is that, since Android was originally designed for small-screen devices, they expected that you would fill the screen with a list and then, when the user clicks an item, move to a new list on a different screen. Thus, the user wouldn't be aware that Android lost track of the selected item.
But this behavior is quite annoying if, for example, you want the user to select an item and then show information about that item on the same screen. If the selection disappears, how is the user supposed to know what they clicked (assuming of course that users have the attention span of a goldfish)?
One possible solution is to change all the list items into radio buttons. I don't really like that solution because it wastes screen real estate. I'd rather just use the background color to show which item is selected. I have seen one solution so far but it is not quite complete or general. So here's my solution:
1. In your XML layout file,
Go to your ListView element and the following attribute: android:choiceMode="singleChoice". I'm not entirely sure what this does (by itself, it doesn't allow the user to select anything) but without this attribute, the code below doesn't work.2. Define the following class.
It is used to keep track of the selected item, and also allows you to simulate pass-by-reference in Java:
public class IntHolder {
public int value;
public IntHolder() {}
public IntHolder(int v) { value = v; }
}
public class IntHolder {
public int value;
public IntHolder() {}
public IntHolder(int v) { value = v; }
}
3. Put the following code somewhere
I'll assume you put it in your Activity, but it could go in any class really:
static void setListItems(Context context, AdapterView listView, List listItems, final IntHolder selectedPosition) { setListItems(context, listView, listItems, selectedPosition, android.R.layout.simple_list_item_1, android.R.layout.simple_spinner_dropdown_item); } static void setListItems(Context context, AdapterView listView, List listItems, final IntHolder selectedPosition, int list_item_id, int dropdown_id) { listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { public void onItemClick(AdapterView<?> list, View lv, int position, long id) { selectedPosition.value = position; } }); ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(context, list_item_id, listItems) { @Override public View getView(int position, View convertView, ViewGroup parent) { View itemView = super.getView(position, convertView, parent); if (selectedPosition.value == position) itemView.setBackgroundColor(0xA0FF8000); // orange else itemView.setBackgroundColor(Color.TRANSPARENT); return itemView; } }; adapter.setDropDownViewResource(dropdown_id); listView.setAdapter(adapter); }