Android Development
OnItemClickListener Issue
ListView Troubleshooting
Mobile App Development
Java Android Debugging

OnItemCLickListener not working in listview

Master System Design with Codemia

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

Introduction

When OnItemClickListener does not fire on a ListView, the problem is usually not the listener registration itself. In most cases, a child view inside the row is stealing focus or touch events, or the row layout has been made clickable in a way that bypasses normal ListView item handling.

Prove the Basic Wiring First

Start with the smallest working example before debugging a complex custom adapter. If the simple case works, the problem is in the row layout or in adapter code.

java
1import android.os.Bundle;
2import android.widget.ArrayAdapter;
3import android.widget.ListView;
4import android.widget.Toast;
5import androidx.appcompat.app.AppCompatActivity;
6import java.util.Arrays;
7
8public class MainActivity extends AppCompatActivity {
9    @Override
10    protected void onCreate(Bundle savedInstanceState) {
11        super.onCreate(savedInstanceState);
12
13        ListView listView = new ListView(this);
14        setContentView(listView);
15
16        ArrayAdapter<String> adapter = new ArrayAdapter<>(
17                this,
18                android.R.layout.simple_list_item_1,
19                Arrays.asList("A", "B", "C")
20        );
21
22        listView.setAdapter(adapter);
23        listView.setOnItemClickListener((parent, view, position, id) -> {
24            String value = (String) parent.getItemAtPosition(position);
25            Toast.makeText(this, "Clicked " + value, Toast.LENGTH_SHORT).show();
26        });
27    }
28}

If this fires correctly, the listener API is fine and the issue is elsewhere.

Child Views Often Consume the Click

The most common cause is a focusable or clickable child inside the custom list item. Buttons, checkboxes, switches, and sometimes even text fields can prevent the row itself from receiving the tap.

A row layout should usually avoid focusable children unless that interaction is intentional.

xml
1<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2    android:layout_width="match_parent"
3    android:layout_height="wrap_content"
4    android:orientation="vertical"
5    android:padding="16dp">
6
7    <TextView
8        android:layout_width="match_parent"
9        android:layout_height="wrap_content"
10        android:text="Row label"
11        android:focusable="false"
12        android:focusableInTouchMode="false"
13        android:clickable="false" />
14</LinearLayout>

If the row includes a button that truly needs its own click behavior, then decide clearly whether the row click or the child click owns the interaction. Trying to make both happen on the same tap often produces confusing results.

Avoid Row-Level Click Handlers That Compete

Another common bug is attaching an OnClickListener directly to the row root in getView. That can interfere with OnItemClickListener and make the ListView callback appear broken.

java
1@Override
2public View getView(int position, View convertView, ViewGroup parent) {
3    View row = convertView;
4    if (row == null) {
5        row = LayoutInflater.from(parent.getContext())
6                .inflate(R.layout.list_item, parent, false);
7    }
8
9    // Avoid doing this unless you intentionally replace item-click handling.
10    // row.setOnClickListener(v -> { ... });
11
12    return row;
13}

If the screen is based on ListView, let ListView own item selection unless you have a strong reason not to.

Check Parent Touch Interception and Overlays

If the list is nested inside a more complicated layout, the tap may never reach the row. Common suspects include:

  • a parent view with an OnTouchListener
  • an invisible overlay above the list
  • nested scrolling containers with aggressive interception
  • a disabled or blocked list area after animation or transition code

A practical debugging step is to temporarily move the ListView into a simple screen with no wrappers. If clicks work there, reintroduce the surrounding layout one piece at a time.

Read the Clicked Item From the Adapter

If the dataset changes frequently, avoid relying on stale cached positions from elsewhere in the code. Use the callback arguments directly.

java
1listView.setOnItemClickListener((parent, view, position, id) -> {
2    Object item = parent.getItemAtPosition(position);
3    Toast.makeText(this, String.valueOf(item), Toast.LENGTH_SHORT).show();
4});

This is not the usual cause of missing clicks, but it prevents a second class of bugs where the click fires yet acts on the wrong row data.

Common Pitfalls

The most common pitfall is putting a focusable child view in the row XML and then expecting the ListView row click to keep working. Another is attaching manual click listeners to row roots in the adapter and accidentally bypassing the list-level callback.

Developers also often debug the full production screen first instead of proving a minimal reproduction. That slows the diagnosis because the real issue is often a single row attribute or parent touch interceptor.

Finally, remember that legacy ListView behavior is sensitive to row structure. If the screen is being modernized anyway, RecyclerView often gives cleaner control over click ownership.

Summary

  • 'OnItemClickListener usually fails because touch is intercepted, not because registration is wrong.'
  • Prove the listener with a minimal built-in row layout first.
  • Remove unnecessary focusable or clickable child views from the row.
  • Avoid competing row-level click handlers inside custom adapters.
  • If the problem persists, isolate parent touch interception and overlays before changing listener code.

Course illustration
Course illustration

All Rights Reserved.