ListView
programming
Android
tutorial
code examples

How to select an item in a ListView programmatically?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Programmatically selecting an item in a ListView is useful when restoring state, jumping to search results, or highlighting newly inserted data. On Android, the exact behavior depends on selection mode, adapter updates, and view lifecycle timing. A reliable implementation sets the selection after data is loaded and keeps selected state in the adapter model.

Basic Programmatic Selection in Android ListView

For simple single-choice lists, set choice mode and call selection methods.

kotlin
1val listView = findViewById<ListView>(R.id.listView)
2listView.choiceMode = ListView.CHOICE_MODE_SINGLE
3
4val items = listOf("Alpha", "Beta", "Gamma", "Delta")
5val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_single_choice, items)
6listView.adapter = adapter
7
8val targetIndex = 2
9listView.setItemChecked(targetIndex, true)
10listView.setSelection(targetIndex)

setItemChecked controls checked state, while setSelection scrolls to the row.

Selecting After Async Data Load

If data arrives asynchronously, select only after adapter update is complete.

kotlin
1fun updateDataAndSelect(newItems: List<String>, index: Int) {
2    val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_single_choice, newItems)
3    listView.adapter = adapter
4
5    listView.post {
6        if (index in newItems.indices) {
7            listView.setItemChecked(index, true)
8            listView.setSelection(index)
9        }
10    }
11}

Posting to UI queue avoids selecting before layout pass finishes.

Select by Value Instead of Hardcoded Index

When list ordering can change, find index by value.

kotlin
1fun selectByValue(value: String, items: List<String>) {
2    val idx = items.indexOf(value)
3    if (idx >= 0) {
4        listView.setItemChecked(idx, true)
5        listView.smoothScrollToPosition(idx)
6    }
7}

This is more robust for sorted or filtered lists.

Handling Custom Adapters

For custom row layouts, keep selected item ID or key in adapter state and update row background in getView. Relying only on visual row state can fail when rows are recycled.

Example adapter state idea:

  • store selectedId
  • call notifyDataSetChanged after selection change
  • style selected row based on current item ID equality

This preserves selection across scroll and view reuse.

Persisting Selection Across Rotation

Store selected position in instance state and restore it after adapter rebind.

kotlin
1override fun onSaveInstanceState(outState: Bundle) {
2    super.onSaveInstanceState(outState)
3    outState.putInt("selected_index", listView.checkedItemPosition)
4}
5
6override fun onRestoreInstanceState(savedInstanceState: Bundle) {
7    super.onRestoreInstanceState(savedInstanceState)
8    val idx = savedInstanceState.getInt("selected_index", -1)
9    if (idx >= 0) {
10        listView.post {
11            listView.setItemChecked(idx, true)
12            listView.setSelection(idx)
13        }
14    }
15}

Without restoration logic, selection can disappear after configuration changes.

ListView Versus RecyclerView

For new Android code, RecyclerView is generally preferred. The selection principles are similar, but state is typically managed in adapter or view model rather than view methods alone. If your project still uses ListView, keep selection management explicit and tested.

Accessibility Considerations

When selecting programmatically, ensure the user still has context. If selection changes due to background events, announce it with accessibility APIs or visible status text so focus changes are understandable.

Testing Selection Behavior

Automated UI tests should verify selection after list refresh, rotation, and filtering. Selection logic often passes manual tests but breaks when item order changes under dynamic data loads. A stable test matrix that covers empty lists, single-item lists, and long lists with scrolling helps catch state bugs early and prevents regressions when adapter code evolves.

Common Pitfalls

  • Calling selection methods before adapter data is attached
  • Using hardcoded indexes when list order changes dynamically
  • Forgetting CHOICE_MODE_SINGLE or multi-choice configuration
  • Relying on row view state without adapter-level selection state
  • Losing selection after rotation because state was not restored

Most issues are timing and state-management problems rather than API limitations.

Summary

  • Set selection after adapter data is ready and list is laid out.
  • Use setItemChecked for checked state and setSelection for scroll.
  • Prefer value-based selection when order can change.
  • Persist selected state across lifecycle events.
  • Keep adapter state as source of truth for custom rows.

Course illustration
Course illustration

All Rights Reserved.