Efficient Implementation of Single Selection Background Color Change in RecyclerView

Dec 01, 2025 · Programming · 10 views · 7.8

Keywords: RecyclerView | background color | single selection

Abstract: This article provides an in-depth exploration of implementing single selection background color changes in Android RecyclerView. By analyzing the core logic of the best answer, it explains how to use the selectedPosition variable to track selected items and efficiently update views with notifyItemChanged(). The article covers ViewHolder design, onBindViewHolder implementation, and performance optimization, offering complete code examples and step-by-step analysis to help developers master standardized methods for single selection highlighting in RecyclerView.

Core Mechanism of Single Selection Background Color Change in RecyclerView

In Android development, RecyclerView serves as a core component for list display, often requiring single selection functionality where visual feedback is crucial. Changing the background color of selected items provides intuitive user indication. The key to implementing this functionality lies in state management and view updates.

State Variable Design

First, two key variables need to be defined to track selection state:

int selectedPosition = -1;
int lastSelectedPosition = -1;

selectedPosition stores the position index of the currently selected item, with an initial value of -1 indicating no selection. lastSelectedPosition records the previously selected position, used to remove highlighting from old items when new items are selected. This design ensures only one item is highlighted at a time.

Optimized ViewHolder Design

The ViewHolder design directly impacts code maintainability and performance. Best practice involves using data binding or direct layout element references:

public class ViewHolder extends RecyclerView.ViewHolder {
  ItemBinding binding;
  
  public ViewHolder(ItemBinding binding) {
    super(binding.getRoot());
    this.binding = binding;
  }
}

Through ItemBinding (assuming ViewBinding or DataBinding), layout elements like LinearLayout or other container views can be safely accessed, avoiding performance overhead from repeated findViewById calls.

onBindViewHolder Implementation Logic

The onBindViewHolder method is central to implementing single selection functionality, handling both click events and view state updates:

public void onBindViewHolder(final ViewHolder holder, final int position) {
  // Set click listener
  holder.binding.getRoot().setOnClickListener(v -> {
    lastSelectedPosition = selectedPosition;
    selectedPosition = holder.getBindingAdapterPosition();
    notifyItemChanged(lastSelectedPosition);
    notifyItemChanged(selectedPosition);
  });
  
  // Set background color based on selection state
  if (selectedPosition == holder.getBindingAdapterPosition()) {
    holder.binding.linearLayout.setCardBackgroundColor(Color.LTGRAY);
  } else {
    holder.binding.linearLayout.setCardBackgroundColor(Color.WHITE);
  }
}

Click event handling logic: When a user clicks an item, the current selectedPosition is first saved to lastSelectedPosition, then selectedPosition is updated to the clicked item's position. Subsequently, notifyItemChanged() is called to notify RecyclerView to update views at these two positions—ensuring the old selected item loses highlighting and the new selected item gains it.

Background color setting logic: By comparing the current item's position with selectedPosition, the method determines whether to apply highlight background color. Here, Color.LTGRAY represents the selected state, while Color.WHITE represents the default state.

Performance Optimization Considerations

Using notifyItemChanged() instead of notifyDataSetChanged() is key for performance optimization. notifyItemChanged() updates only the specified position's view, whereas notifyDataSetChanged() triggers a complete list redraw, which can cause performance issues with large datasets.

Additionally, ensure view lookups are completed in the ViewHolder constructor to avoid repeated findViewById calls in onBindViewHolder, aligning with RecyclerView's view recycling mechanism.

Complete Implementation Example

Integrating with the original question's code structure, a complete adapter implementation is as follows:

public class RecyclerDataAdapter extends RecyclerView.Adapter<RecyclerDataAdapter.ViewHolder> {
  private String[] android_versionnames;
  private int selectedPosition = -1;
  private int lastSelectedPosition = -1;
  
  @Override
  public void onBindViewHolder(final ViewHolder holder, final int position) {
    holder.itemView.setOnClickListener(v -> {
      lastSelectedPosition = selectedPosition;
      selectedPosition = holder.getBindingAdapterPosition();
      
      if (lastSelectedPosition != -1) {
        notifyItemChanged(lastSelectedPosition);
      }
      notifyItemChanged(selectedPosition);
    });
    
    // Set text content
    holder.tv1.setText(android_versionnames[position]);
    
    // Set background color
    if (selectedPosition == position) {
      holder.row_linearlayout.setBackgroundColor(Color.LTGRAY);
    } else {
      holder.row_linearlayout.setBackgroundColor(Color.WHITE);
    }
  }
  
  // ViewHolder and other methods remain unchanged
}

This implementation preserves the original code structure while integrating single selection highlighting. Note the addition of a lastSelectedPosition != -1 check to avoid updating invalid positions in the initial state.

Extensions and Variations

In practical development, more complex selection logic may be required, such as:

  1. Multi-selection mode: Use Set<Integer> instead of selectedPosition to store multiple selected positions.
  2. Persistent selection state: Restore selection state after configuration changes (e.g., screen rotation) by saving selectedPosition in onSaveInstanceState.
  3. Custom highlight effects: Beyond background color, modify text color, add borders, or use animation transitions.

By understanding the core state management and view update mechanisms, developers can flexibly adapt to various selection requirements.

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.