OnItemCLickListener not working in listview
Asked Answered
F

25

252

Activity class code:

conversationList = (ListView)findViewById(android.R.id.list);
ConversationArrayAdapter conversationArrayAdapter=new  ConversationArrayAdapter(this, R.layout.conversation_list_item_format_left, conversationDetails);
conversationList.setAdapter(conversationArrayAdapter);
conversationList.setOnItemClickListener(new AdapterView.OnItemClickListener(){ 
    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
        Log.d("test","clicked");
    }
});

The getView function in the Adapter class:

if (v == null) {                                
    LayoutInflater vi = (LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    if(leftSideMessageNumber.equals(m.getTo())) {
        v = vi.inflate(R.layout.conversation_list_item_format_left, null);
    } else {
        v = vi.inflate(R.layout.conversation_list_item_format_right, null);
    }
}

Is there a problem with using two xmls while inflating?

Foretime answered 5/4, 2011 at 11:25 Comment(1)
@Foretime My issue was that i was using imagebuttons in my layout cells. Even after adding "android:descendantFocusability" my click listener was not responding. What i did was, i changed all the ImaegButtons to ImageViews. That resolved my issue.Leighton
U
750

I just found a solution from here, but by deep clicking.

If any row item of list contains focusable or clickable view then OnItemClickListener won't work.

The row item must have a param like android:descendantFocusability = "blocksDescendants".

Here you can see an example of how your list item should look like. Your list item xml should be... row_item.xml (your_xml_file.xml)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:baselineAligned="false"
    android:descendantFocusability="blocksDescendants"
    android:gravity="center_vertical" >

    // your other widgets here

</LinearLayout>
Upbear answered 17/1, 2013 at 5:32 Comment(3)
You can also set this programatically with listView.setDescendantFocusability(int focus); where focus is one of ViewGroup.FOCUS_BEFORE_DESCENDANTS, ViewGroup.FOCUS_AFTER_DESCENDANTS or ViewGroup.FOCUS_BLOCK_DESCENDANTSDierdre
My question is this is an android bug or is it by design?Sign
Hours trying to figure this out! Thanks. Note that with nested LinearLayouts for a row item, the top-most LinearLayout must not have android:descendantFocusability="blocksDescendants". All others need it.Dhahran
O
96

The problem is that your layouts contain either focusable or clickable items. If a view contains either focusable or clickable item the OnItemCLickListener won't be called.

Click here for more information.

Please post one of your layout xmls if that isn't the case.

Olnee answered 7/4, 2011 at 21:37 Comment(0)
C
72

For my lists, my rows have other things that can be clicked, like buttons, so doing a blanket blocksDescendants doesn't work. Instead I add a line in the button's xml:

    android:focusable="false"

That keeps the buttons from blocking the clicks on the rows, but still lets the buttons take the clicks, too.

Centuple answered 6/5, 2013 at 18:6 Comment(1)
Only way I could get a GridView with RadioButtons in it working was to apply android:descendantFocusability="blocksDescendants" on the LinearLayout containing the RadioButton, and by setting android:clickable="false" in the RadioButton itself.Bilection
T
38

you need to do 2 steps in your listview_item.xml

  1. set the root layout with: android:descendantFocusability="blocksDescendants"
  2. set any focusable or clickable view in this item with:
    android:clickable="false"
    android:focusable="false"
    android:focusableInTouchMode="false"

Here is an example: listview_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="10dp"
    android:layout_marginTop="10dp"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:gravity="center_vertical"
    android:orientation="vertical"
    android:descendantFocusability="blocksDescendants">

    <RadioButton
        android:id="@+id/script_name_radio_btn"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textStyle="bold"
        android:textColor="#000"
        android:padding="5dp"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        />

</LinearLayout>
Tangible answered 1/6, 2015 at 3:17 Comment(2)
Setting clickable="true on the item view will make the onItemClick to not be called. So pay attention to also add clickable="false" on the item root view, in this case is the LinearLayoutBrescia
If you have the same layout as landscape, etc. make sure you do it there as well.Espousal
F
22

use the below code inside button tag in custom row layout of listview

 android:focusable="false"
 android:clickable="false"
Folkways answered 30/5, 2013 at 12:39 Comment(0)
D
19

Use android:descendantFocusability

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="80dip"
    android:background="@color/light_green"
    android:descendantFocusability="blocksDescendants" >

Add above in root layout

Denomination answered 16/12, 2013 at 10:36 Comment(1)
Adding details might make this a better answer and +1.Cold
I
18

I had the same problem and I just saw I had accidentally set:

@Override
public boolean isEnabled(int position)
{
    return false;
}

on my CustomListViewAdapter class.

By changing this to:

return true;

I've managed to fix the problem. Just in case if someone has done the same mistake...

Inductance answered 29/7, 2013 at 9:59 Comment(0)
E
11

I solved it with the help of this answer

1.Add the following in Linear Layout of list_items.xml android:descendantFocusability="blocksDescendants"

2.Child Views of LinearLayout in list_items.xml

 android:focusable="false" 
Elderly answered 24/2, 2017 at 5:33 Comment(0)
H
10

if you have textviews, buttons or stg clickable or selectable in your row view only

android:descendantFocusability="blocksDescendants"

is not enough. You have to set

android:textIsSelectable="false"

to your textviews and

android:focusable="false"

to your buttons and other focusable items.

Hosea answered 14/10, 2014 at 12:3 Comment(0)
T
10

Even I was having the same problem, I am having checkbox, did the following to masker itemClickListener work,

Added the following properties to the checkbox,

android:focusable="false"
android:focusableInTouchMode="false"
android:clickable="false"

and ItemClickListner started working.

For detailed example you can go through the link,

http://knowledge-cess.com/android-itemclicklistner-with-checkbox-or-radiobutton/

Hope it helps Cheers!!

Tadeo answered 25/5, 2015 at 11:31 Comment(0)
H
5

I had the same problem and tried all of the mentioned solutions to no avail. through testing i found that making the text selectable was preventing the listener to be called. So by switching it to false, or removing it my listener was called again.

android:textIsSelectable="false"

hope this helps someone who was stuck like me.

Hoffert answered 14/7, 2013 at 19:33 Comment(0)
H
5
  1. Add this in main Layout

    android:descendantFocusability="blocksDescendants"
    
  2. Write this code into every button,Textview,ImageView etc which have onClick

    android:focusable="false"
    
    android:clickable="false"
    

Hope it will work.

Hampton answered 19/1, 2018 at 11:5 Comment(0)
S
3

Two awesome solutions were this, if your extending ListFragment from a fragment, know that mListView.setOnItemClickListener wont be called before your activity is created, this ensured it is set when activity has been created

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    mListView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int position, long rowId) {
            // Do the onItemClick action

            Log.d("ROWSELECT", "" + rowId);
        }
    });
}

While looking at the source code for ListFragment, I came across this

public class ListFragment extends Fragment {
    ...........................................
    ................................................

    final private AdapterView.OnItemClickListener mOnClickListener
                = new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
            onListItemClick((ListView)parent, v, position, id);
        }
    };

    ................................................................
    ................................................................

    public void onListItemClick(ListView l, View v, int position, long id) {
    }
}

An onItemClickListener object is attached and it calls onListItemClick() As such the other similar solution, which works in the exact same way is to override onListItemClick()

@Override
public void onListItemClick(ListView l, View v, int position, long rowId) {
    super.onListItemClick(l, v, position, id);
   // Do the onItemClick action

   Log.d("ROWSELECT", "" + rowId);
} 
Stereoscopic answered 10/6, 2015 at 7:17 Comment(0)
E
3

in my case none of xml layout properties was not helpful.

I just add a single line of code like this: convertView.setClickable(false);

@NonNull
@Override
public View getView(final int position, View convertView, @NonNull ViewGroup parent) {
    ViewHolder viewHolder;
    if (convertView == null || convertView.getTag() == null) {
        LayoutInflater inflater = LayoutInflater.from(context);
        convertView = inflater.inflate(R.layout.my_layout_id, parent, false);
        viewHolder = new ViewHolder(convertView);
        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }
    ...
    convertView.setClickable(false);
    return convertView;
}

so basically it do the same thing as setting up properties in xml layout but it was only thing which works in my case.

It is not perfect timing but maybe it will helps somebody Happy coding

Exocrine answered 24/7, 2018 at 23:55 Comment(0)
P
1

I've tried all the above and NOTHING worked.

I solved the problem as follows:

First I define a custom Button called ListButton

public class ListButton extends android.widget.Button
{

private ButtonClickedListener clickListener;

public ListButton(Context context)
{
    this(context, null);
}

public ListButton(Context context, AttributeSet attrs)
{
    this(context, attrs, 0);
}

public ListButton(Context context, AttributeSet attrs, int defStyle)
{
    super(context, attrs, defStyle);
}

public void setClickListener(ButtonClickedListener listener) {
    this.clickListener = listener;
}

@Override
public boolean isInTouchMode() {
    return true;
}

@Override
public boolean onTouchEvent(MotionEvent event) {

    return false;
}

@Override
public boolean dispatchTouchEvent(MotionEvent event) {

    switch (event.getAction()) 
      {
          case MotionEvent.ACTION_DOWN:
              break;
          case MotionEvent.ACTION_UP:

              eventClicked();

              break;
          case MotionEvent.ACTION_CANCEL:
              break;
          case MotionEvent.ACTION_MOVE:
              break;
          default :

      }
    return true;
}

private void eventClicked() {
    if (this.clickListener!=null) {
        this.clickListener.ButtonClicked();
    }
}

}

The XML looks like:

<dk.example.views.ListButton
android:id="@+id/cancel_button"
android:layout_width="125dp"
android:layout_height="80dp"
android:text="Cancel"
android:textSize="20sp" 
android:layout_margin="10dp"
android:padding="2dp"
android:background="#000000"
android:textColor="#ffffff"
android:textStyle="bold"  
/>

Then I define my own ButtonClicked Listener interface:

public interface ButtonClickedListener {
    public void ButtonClicked();
}

Then I use my own listener just as if it was the normal OnClickListener:

final ListButton cancelButton = (ListButton) viewLayout.findViewById(R.id.cancel_button);

    cancelButton.setClickListener(new ButtonClickedListener() {

        @Override
        public void ButtonClicked() {
            //Do your own stuff here...
        }

    });
Panier answered 15/10, 2015 at 9:16 Comment(0)
L
1

Android:autoText attribute also makes TextView auto focusable.

Luminance answered 3/4, 2018 at 7:17 Comment(0)
E
1

I had the same issue, I was using a style for my texts in the row layout that had the "focusable" attribute. It worked after I removed it.

Exuberant answered 27/11, 2018 at 22:47 Comment(0)
U
1

In my case, I had to remove the next line from the Layout

android:clickable="true"
Utu answered 21/10, 2019 at 11:1 Comment(0)
E
0

If you want to use both the simple click and long click on list view items better way to implement that would be to use context menu for long click. Avoid using setItemLongClickListener especially if you have multiple row layouts for your listview.

Eelworm answered 13/1, 2016 at 12:17 Comment(0)
S
0

Faced same problem, tried for hours. If you have tried all of the above than try changing layout_width of Listview and list item to match_parent from wrap_content.

Scalable answered 30/11, 2016 at 8:15 Comment(0)
A
0

All of the above failed for me. However, I was able to resolve the problem (after many hours of banging my head - Google, if you're listening, please consider fixing what I encountered below in the form of compiler errors, if possible)

You really have to be careful of what android attributes you add to your xml layout here (in this original question, it is called list_items.xml). For me, what was causing the problem was that I had switched from an EditText view to a TextView and had leftover attribute cruft from the change (in my case, inputType). The compiler didn't catch it and the clickability just failed when I went to run the app. Double check all of the attributes you have in your layout xml nodes.

Armament answered 21/3, 2017 at 2:0 Comment(0)
G
0
private AdapterView.OnItemClickListener onItemClickListener;

@Override
public View getView(final int position, View convertView, final ViewGroup parent) {
 .......

final View view = convertView;
convertView.setOnClickListener(new View.OnClickListener() {
    @Override
     public void onClick(View v) {
         if (onItemClickListener != null) {
             onItemClickListener.onItemClick(null, view, position, -1);
         }
      }
 });

return convertView;
}

public void setOnItemClickListener(AdapterView.OnItemClickListener onItemClickListener) {
    this.onItemClickListener = onItemClickListener;
}

Then in your activity, use adapter.setOnItemClickListener() before attaching it to the listview.

Copied from github its worked for me

Goodrow answered 23/12, 2018 at 10:52 Comment(0)
S
0

The thing that worked for me was to add the below code to every subview inside the layout of my row.xml file:

android:focusable="false"
android:focusableInTouchMode="false"

So in my case:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:id="@+id/testingId"
        android:text="Name"
       //other stuff 
        />

    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:id="@+id/dummyId"
        android:text="icon"
        //other stuff 
        />

    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:id="@+id/assignmentColor"
       //other stuff 
       />

    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:id="@+id/testID"
        //other stuff 
        />

    <TextView
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:text="TextView"
        //other stuff 
        />

</android.support.constraint.ConstraintLayout>

And this is my setOnItemClickListener call in my Fragment subclass:

CustomListView = (PullToRefreshListCustomView) layout.findViewById(getListResourceID());
        CustomListView.setAdapter(customAdapter);
        CustomListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Log.d("Testing", "onitem click working");
              //  other code
            }

        });

I got the answer from here!

Saveloy answered 15/2, 2019 at 11:42 Comment(0)
R
0

Had the same problem with onClick. The solution was to remove from the xml the following

android:tooltipText=""
Retool answered 24/1, 2022 at 19:18 Comment(0)
I
-1

I solved the problem by removing the clickable views from the list.

Intelligibility answered 8/12, 2019 at 8:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.