Can't click on ListView row with imagebutton
AndroidListviewImagebuttonAndroid Problem Overview
I have trouble with a ListView
. Its items (rows) have an ImageButton
.
The ImageButton
has android:onClick
set, so this onClick
event is working, but click on row doesn't work.
If I remove the ImageButton
from the row item, click on row works (ListView
has correct onClick
listener). How can I fix it?
I need onClick
event when the user clicks on the ImageButton
, and the standard click event when the user selects the row (not click the ImageButton
but click the row).
My ListView:
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/restaurants_list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:divider="@color/list_devider"
android:dividerHeight="1dp"
android:cacheColorHint="@color/list_background" />
Android Solutions
Solution 1 - Android
Unfortunately,
android:focusable="false"
android:focusableInTouchMode="false"
doesn't work for ImageButton
.
I finally found the solution here. In your layout xml for those items, add
android:descendantFocusability="blocksDescendants"
to the root view.
It works perfectly for a ListView
that has ImageButton
s. According to official reference, blocksDescendants
means that the ViewGroup
will block its descendants from receiving focus.
Solution 2 - Android
You can use a custom adapter for your listView (if you haven't already). And there, in the getView(int position, View inView, ViewGroup parent)
method of the adapter do something like this:
@Override
public View getView(int position, View inView, ViewGroup parent) {
View v = inView;
ViewHolder viewHolder; //Use a viewholder for sufficent use of the listview
if (v == null) {
LayoutInflater inflater = (LayoutInflater) adaptersContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.list_item, null);
viewHolder = new ViewHolder();
viewHolder.image = (ImageView) v.findViewById(R.id.ImageView);
v.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) v.getTag();
}
.....
viewHolder.image.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//Click on imageView
}i
});
v.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//Click on listView row
}
});
.....
return (v);
}
See here if you need help creating your custom adapter.
Solution 3 - Android
If a row of listView have any clickable element like Button
, Image
..etc..then onItemClick
will not work. So you need to write the click listener in getView
of your list adapter.
For more read this.
Solution 4 - Android
Set these properties for your button:
android:focusable="false"
android:focusableInTouchMode="false"
Or you can set it dynamically in your adapter class:
yourButton.setFocusable(false);
yourButton.setFocusableInTouchMode(false);
And make sure that you set the choice mode as single for the listview:
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
Solution 5 - Android
In my case, android:descendantFocusability="blocksDescendants"
for main layer did not work, neither in the ListView. I also tried android:focusable="false" android:focusableInTouchMode="false"
which I heard that it is working for Buttons, but I had ImageButton so it didn't.
But setting the properties of the button in the CS file of the Layout worked.
var imageButton = view.FindViewById<ImageButton>(Resource.Id.imageButton1);
imageButton.Focusable = false;
imageButton.FocusableInTouchMode = false;
imageButton.Clickable = true;
Solution 6 - Android
If a row has multiple clickable elements, onItemClick() will not work. You will need to set the OnClickListener
in the getView()
method. Store the listeners the the View's tag so that they can be recycled, add methods to your listeners so they can be specialized for different rows.
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
RowClickListeners listeners = (RowClickListeners) view.getTag();
if (listeners == null) {
listeners = new RowClickListeners();
}
// Row click listener:
RowClickListener onClickListener = listeners.rowClickListener;
if (onClickListener == null) {
onClickListener = new RowClickListener();
listeners.rowClickListener = onClickListener;
}
onClickListener.setToPosition(pos);
view.setOnClickListener(onClickListener);
// Overflow listener:
View btn = view.findViewById(R.id.ic_row_btn);
ButtonListener btnListener = listeners.buttonClickListener;
if (rowListener == null) {
btnListener = new ButtonListener(activity);
listeners.rowClickListener = btnListener;
}
btnListener.setToPosition(pos);
btnListener.setCollection(collectionId);
btn.setOnClickListener(btnListener);
}
public static class RowClickListeners {
public RowClickListener rowClickListener;
public ButtonListener buttonClickListener;
}
Solution 7 - Android
no single answer above worked for me, but a combination did.
I now set android:descendantFocusability="blocksDescendants"
on the ListView and android:focusable="false" android:focusableInTouchMode="false"
on the ImageButtons in the XML AND in Java I also set descendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS)
on the ListView and focusable(false), focusableInTouchMode(false), clickable(true)
on the ImageButtons.