45

I've looked everywhere for a solution to this, but I can't figure out how to implement it. My OnItemClickListener was disabled somehow on my ListView rows, because I have an ImageButton in the row layout, which takes over the focus. There have been numerous questions I've found, but none of them have gotten me anywhere.

I've checked this question, but I couldn't really make heads or tails of it. I just need a way to get the rows clickable so that I can detect when a row is pressed. Long press and focus work fine.

Community
  • 1
  • 1
Kleptine
  • 5,089
  • 16
  • 58
  • 81

12 Answers12

60

Instead of an OnItemClickListener, add an OnClickListener to each of your views returned from your adapter. You'll need to use setItemsCanFocus setting up your list:

ListView list = (ListView) findViewById(R.id.myList);
list.setAdapter(new DoubleClickAdapter(this));
list.setItemsCanFocus(true);

and then in your Adapter's getView, this will yield a clickable row. The button is assumed to be in the inflated xml.

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View view = View.inflate(context, R.layout.cell, null);
    view.setClickable(true);
    view.setFocusable(true);
    view.setBackgroundResource(android.R.drawable.menuitem_background);
    view.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            new AlertDialog.Builder(context).setTitle("touched").show();
        }

    });
    return view;
}
CSchulz
  • 10,882
  • 11
  • 60
  • 114
jqpubliq
  • 11,874
  • 2
  • 34
  • 26
  • 47
    Don't forget to recycle views! Use the convertView, do not inflate a new one every time. – Romain Guy Mar 03 '10 at 07:36
  • I had basically done that, though I feel like I had problems doing something. I'll try it out again, maybe it was just a stupid mistake. – Kleptine Mar 03 '10 at 14:41
  • Okay, can anyone explain *why* the ListView controls aren't working as advertised? I've had this same issue too and this solution works though the response time on touch is not good. – greg7gkb Jun 11 '10 at 01:46
  • Old question I know but you can also create the onclicklistner in the "newView" method of your adapter instead. This will save this process being called every time the user scrolls the list – RBI Mar 06 '12 at 17:30
  • 1
    This is not an ideal solution if you still want your whole row to be clickable, you should use http://stackoverflow.com/a/4518810/9636 – Heath Borders Apr 12 '14 at 04:13
  • this does not work if i do it in `newView()` of an extended `CursorAdaptor`, instead of in a `getView()`. What's wrong? – faizal Sep 12 '14 at 13:21
  • I have been stuck on this for 6 hours now, and I really need help. http://stackoverflow.com/questions/35108940/why-cant-i-remove-an-item/35109304#35109304 – Ruchir Baronia Jan 31 '16 at 03:03
53

set your ImageButton's attribute:

android:focusable="false"

Because AbsListView.onTouchEvent check child.hasFocusable().

Charuක
  • 12,953
  • 5
  • 50
  • 88
meizilp
  • 3,911
  • 3
  • 28
  • 11
10

I've tested the following solution on SDK levels 8 and 16.

In getView()

setFocusable(false);
setClickable(false);

rather than setting them true in the Adapter's getView() does what I think the original question wanted, and means that an OnItemClickListener gets called, provided that an OnClickListener is not set in getView().

I'm assuming that anything you can do in an View's OnClickListener you can do just as easily in a ListView's OnItemClickListener. (setOnClickListener on a View implicitly sets the view to be clickable, which prevents the ListView's corresponding OnItemClickListener getting called, apparently.)

The behaviour is as one would expect, in terms of the ImageButton's visual state when the item is pressed or rolled over.

The solution is a slight illusion, in that it is the list item that's being pressed not the ImageButton itself, so if the button doesn't occupy whole list item, clicking somewhere else in the item will still make the button's drawable state reflect the click. Same for focus. That might be a price worth paying.

JulianSymes
  • 2,135
  • 22
  • 24
  • 4
    If your ListView row has multiple clickable items, you can probably achieve exactly what you want by setting `android:descendantFocusability="blocksDescendants"` on the top level list item layout, and not setting an `OnClickListener` on the view that you return from getView(). Setting `OnClickListener`s on the individual items will still work. – JulianSymes Sep 20 '12 at 14:26
  • 1
    This solution also worked for me. In my case I was not getting clicked event in OnItemClickListener when RadioButton was clicked. – HemangNirmal Feb 02 '15 at 13:08
  • I have been stuck on this for 6 hours now, and I really need help. http://stackoverflow.com/questions/35108940/why-cant-i-remove-an-item/35109304#35109304 – Ruchir Baronia Jan 31 '16 at 03:03
7

This will definitely work. Add this to the layout definition.

android:descendantFocusability="blocksDescendants" 

Found the solution here

Kapil Raju
  • 685
  • 1
  • 8
  • 12
5

best way to do is this:

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

set these properties for that Imagebutton and try. I

Charuක
  • 12,953
  • 5
  • 50
  • 88
silentkratos
  • 941
  • 2
  • 11
  • 9
5

One alternative to setting an OnClickListener for every view is to NOT use an ImageButton - use an ImageView instead. The ImageView can still send events to an OnClickListener and won't take over the focus.

Sastrija
  • 3,284
  • 6
  • 47
  • 64
humbleCoder
  • 53
  • 1
  • 2
4

For my version of this problem, the issue was that I had set my TextView object to android:inputType="textMultiLine". When I removed this line the issue of the list not being clickable was gone. Looks like a nasty little bug.

Also, I'm still able to use the android:minLines/android:maxLines properties with no problem, so it's not a big issue. Just not the solution I expected.

user229044
  • 232,980
  • 40
  • 330
  • 338
greg7gkb
  • 4,933
  • 4
  • 41
  • 55
  • I have been stuck on this for 6 hours now, and I really need help. http://stackoverflow.com/questions/35108940/why-cant-i-remove-an-item/35109304#35109304 – Ruchir Baronia Jan 31 '16 at 03:04
1

The following line solved the issue in my project:

<TextView ... android:textIsSelectable="false" />
Tunaki
  • 132,869
  • 46
  • 340
  • 423
hogi
  • 896
  • 8
  • 7
1

As an alternative solution which worked for me you can try to extend your adapter from BaseAdapter (iso implementing ListAdapter interface)

Charuක
  • 12,953
  • 5
  • 50
  • 88
0

Put This code ImageView nextpage= (ImageView)findViewById(R.id.btnEdit); instead of ImageButton . now the list item is active

Charuක
  • 12,953
  • 5
  • 50
  • 88
newb
  • 31
  • 5
0

I have sub-classed ImageButton and setFocusable="false" in layout definition didn't work for me. It solved calling setFocusable(false) in constructor of subclass.

Charuක
  • 12,953
  • 5
  • 50
  • 88
Lukas Novak
  • 1,149
  • 11
  • 11
-1

Using a ScrollView can prevent the onItemClickListener from receiving the input.

Hope this helps anyone.

Charuක
  • 12,953
  • 5
  • 50
  • 88