Implementing Persistent Highlight for Selected Items in Android ListView

Nov 24, 2025 · Programming · 11 views · 7.8

Keywords: Android | ListView | Selection Highlight | Selector | View Recycling

Abstract: This article provides a comprehensive technical analysis of implementing persistent highlight for selected items in Android ListView. It covers both XML configuration and programmatic approaches, explaining the selection mode mechanism and view recycling principles. The focus is on correct implementation using Selectors and StateListDrawable, with comparisons of different methods and solutions to common issues like multiple selections and display errors due to view reuse.

Introduction

In Android application development, ListView is a commonly used component for displaying lists, and its interaction experience directly impacts user satisfaction. A frequent requirement is to maintain the visual highlight of a selected item while displaying related details in another area. This article provides an in-depth analysis of the implementation mechanisms for persistent highlight of selected ListView items, based on practical development scenarios.

Problem Analysis

In typical dual-list layouts, the left ListView displays the main items, while the right ListView shows details of the selected item. The core requirement is: when a user selects an item in the left list, that item should maintain its selected visual state until another item is chosen. Common errors in initial implementations include:

XML Configuration Method

Configuring ListView selection behavior directly through XML layout files is the most concise and effective approach. Add the following attributes to the ListView tag:

<ListView
    android:id="@+id/cli_lista"
    android:layout_width="512dp"
    android:layout_height="wrap_content"
    android:choiceMode="singleChoice"
    android:listSelector="@drawable/bg_key"
    android:fadeScrollbars="false">
</ListView>

Here, android:choiceMode="singleChoice" specifies single selection mode, ensuring only one item is selected at a time. The android:listSelector attribute defines the drawable resource for the selected state.

Selector Resource Definition

Create the res/drawable/bg_key.xml file to define backgrounds for different states:

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

Define color values in res/values/colors.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="pressed_color">#4d90fe</color>
    <color name="default_color">#ffffff</color>
</resources>

Programmatic Implementation

In addition to XML configuration, ListView selection behavior can be set dynamically through code:

ListView listView = findViewById(R.id.cli_lista);
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
listView.setSelector(R.drawable.bg_key);

Set the selected state in the onItemClick listener:

listView.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long arg3) {
        view.setSelected(true);
        // Other business logic
    }
});

Technical Principle Analysis

ListView's view recycling mechanism is key to understanding persistent selection states. When the list scrolls, views that move off-screen are recycled and reused for new items entering the screen. This means:

How selection modes work:

In-depth Analysis of StateListDrawable

The StateListDrawable implementation from the reference article demonstrates lower-level control:

ColorDrawable pressedDrawable = new ColorDrawable(Color.GRAY);
ColorDrawable normalDrawable = new ColorDrawable(Color.YELLOW);

StateListDrawable selector = new StateListDrawable();
selector.addState(new int[]{android.R.attr.state_pressed}, pressedDrawable);
selector.addState(new int[]{-android.R.attr.state_pressed}, normalDrawable);

listView.setSelector(selector);

This approach offers greater flexibility for customizing various state combinations.

Common Issues and Solutions

Issue 1: Multiple Selections
Cause: Incorrect selection mode setting or erroneous manual background modifications
Solution: Use choiceMode="singleChoice" and avoid manual background changes

Issue 2: Lost Selection State After Scrolling
Cause: View recycling causing improper state restoration
Solution: Rely on the system's selector mechanism instead of directly manipulating views

Issue 3: Performance Problems
Cause: Complex custom selectors or frequent state updates
Solution: Optimize selector resources, use lightweight colors or simple shapes

Best Practice Recommendations

  1. Prefer XML configuration for better code maintainability
  2. Define clear color contrasts for different states
  3. Test scrolling performance in large lists
  4. Consider accessibility requirements, ensure sufficient visual distinction for selected states
  5. Maintain consistent selection styles throughout the application for unified user experience

Complete Implementation Example

Complete implementation combining the problem scenario:

// Initialize client list
Cursor cursor = db.rawQuery("Select NrCl||';'||Nome From Clientes", null);
final ListView clientList = findViewById(R.id.cli_lista);
ArrayAdapter<String> clientAdapter = new ArrayAdapter<String>(this, 
    android.R.layout.simple_list_item_activated_1, listItems);
clientList.setAdapter(clientAdapter);
clientList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

// Detail list
final ListView detailList = findViewById(R.id.cli_lista_detalhe);
final ArrayAdapter<String> detailAdapter = new ArrayAdapter<String>(this, 
    android.R.layout.simple_list_item_1, listItems2);

detailList.setAdapter(detailAdapter);

// Click event handling
clientList.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        // Set selection state
        clientList.setItemChecked(position, true);
        
        // Update detail display
        String item = ((TextView)view).getText().toString();
        String[] strArray = item.split("\\;");
        
        cli.load(strArray[0]);
        listItems2.clear();
        listItems2.add("Nome: " + cli.getNome());
        listItems2.add("Morada: " + cli.getMorada());
        // ... other detail fields
        
        detailAdapter.notifyDataSetChanged();
    }
});

Conclusion

By correctly using ListView's selection modes and selector mechanisms, persistent highlight of selected items can be reliably implemented. The XML configuration method is concise and efficient, while programmatic implementation offers more flexibility. Understanding the view recycling principle is crucial for avoiding common pitfalls. The methods discussed in this article are applicable to most Android versions and provide a complete technical solution for developing high-quality list interaction experiences.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.