Monday, January 30, 2012

Multiple Click Handlers on a List View Row in Android

Recently a reader asked a interesting question. The reader asked how to handle multiple buttons within a list view item, while still being able to scroll the list and click on the list item itself. In Android, when you introduce a view that has drawable states to to a list view, any touch events that the list view would normally handle no longer work, because all touch events are now being used by the new view that was added.


This is actually by design in Android. Any time a click-able view comes into place, it takes presidents over any touch events below it. There is a way to get it working the way your expecting, where you can click on the buttons while having touch events handled by the list view. Here is one way you could do it:


First, you need to set your ListView to allow focus-able views. This lets you set which views can be focused on a given list item. Add this line to your activity where you are setting up your list view (probably onCreate or onResume):

   1: getListView().setItemsCanFocus(true); 

Next, in your List View Adapter’s getView method, where your setting up your buttons, you need to add a few lines to each view that you want to be clickable. In your case, it would be each button, and the main layout View that was inflated. You just add the three lines below to each of those views (your two buttons, and your main layout).

   1: v.setClickable(true);
   2: v.setFocusable(true);
   3: v.setBackgroundResource(android.R.drawable.menuitem_background);  

Hope that helps! Let me know if it works out for you.

1 comment:

  1. Hi,

    When I reach the last visible position and click down the listview does not scroll. However, if I touch and scroll the listview then try to navigate the listview using my custom focus control, it works.

    Do you know what state android puts a listview in when the user touch and scrolls it? so I can set it manually or do you know another way of fixing this?

    Thanks.

    ReplyDelete