Android ImageButton in ListView blocking onItemClick() - android

I'm trying to add a ListView that has an ImageButton in it. Everything works except my onItemClick() isn't called. I've googled around and searched on StackOverflow to find suggestions of
android:descendantFocusability="blocksDescendants"
and
android:focusable="false"
I've tried both of these but neither work. This my layout file.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="#dimen/listview_item_height"
android:descendantFocusability="blocksDescendants" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingStart="#dimen/activity_horizontal_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingEnd="#dimen/activity_horizontal_margin"
android:layout_gravity="center_vertical"
android:orientation="vertical" >
<TextView
android:id="#+id/song_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="#dimen/listview_item_title_text_size"
android:textColor="#color/text_primary"
android:ellipsize="end"
android:singleLine="true"
android:lines="1" />
<TextView
android:id="#+id/song_artist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="#dimen/listview_item_subtitle_text_size"
android:textColor="#color/text_secondary"
android:ellipsize="end"
android:singleLine="true"
android:lines="1" />
</LinearLayout>
<TextView
android:id="#+id/song_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical" />
<ImageButton
android:id="#+id/overflow_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="8dp"
android:background="?android:selectableItemBackground"
android:src="#drawable/ic_action_overflow"
android:scaleX="0.75"
android:scaleY="0.75" />
</LinearLayout>
Then my onItemClick() simply logs the id of the element clicked.
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
long id = adapter.getItemId(position);
Log.d(TAG, id + "");
}
I never get the output in the console though. I do get the selectable background when I click on the item though. I did not get that until adding "blocksDescendants" to the code. Any help is appreciated as I've spent a bit of time on this already.

You can use imagsView instead of imageButton and do onClick actions when list item is clicked
Or
You set onClickListener after layout is inflated in view adapter.
Read this: http://androidforbeginners.blogspot.it/2010/03/clicking-buttons-in-listview-row.html?m=1
Also this should be set like this to let system listen for clicks:
ListView focusable
android:focusable="true"
Button not focusable
android:focusable="false"
Or
You can use this in xml. On click, it will look for your method in same activity. Doesn't work for fragments.
android:onClick="myMethod"

Have you tried using an ImageView instead? That way by default it won't intercept your clicks.
Or you could try playing with onInterceptTouchEvent.
http://developer.android.com/training/gestures/viewgroup.html

Related

Why does adding a Button to (Android) ListView item shut down tap listener events for the item itself?

I have some pretty simple xml defining a ListView item. Each item contains 2 TextView widgets and a Button. I only added the Button yesterday, and suddenly taps on the ListView item itself no longer produce onItemClick() events.
I have reproduced this carefully and simply removing the Button entry in the XML for the ListItem allows the onItemClick() events to be fired. Answers to other SO questions showed it is possible for controls placed on a ListView item could capture or otherwise prevent tap events from firing the listener (see here for example). So, hoping to find a workaround I added the following 3 lines to my TextView controls to no effect:
android:focusable="false"
android:textIsSelectable="false"
android:clickable="false"
My xml displays everything properly and is:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="#+id/linLyt"
>
<TextView
android:id="#+id/tvVal1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="left"
android:layout_gravity="left|center_vertical"
android:text="0."
android:textSize="16sp"
android:maxLines="1"
android:layout_weight=".15"
/>
<TextView
android:id="#+id/tvVal2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:gravity="left"
android:layout_gravity="center_vertical"
android:text=""
android:textSize="16sp"
android:maxLines="1"
android:layout_weight=".55"
android:focusable="false"
android:textIsSelectable="false"
android:clickable="false"
/>
<Button
android:id="#+id/btnClickMe"
android:layout_width="0dp"
android:layout_height="40dp"
android:gravity="right|center_vertical"
android:layout_gravity="right"
android:textColor="#color/CornflowerBlue"
android:text="Click"
android:minHeight="0dp"
android:minWidth="0dp"
android:textSize="16dp"
android:maxLines="1"
android:layout_weight=".3"
android:background="?android:attr/selectableItemBackground"
/>
</LinearLayout>
Again, just simply remove or comment out the Button xml and suddenly the listener begins firing again.
Add this :
android:descendantFocusability="blocksDescendants"
in your root layout of listview to make the listview Item click listener to work. blocksDescendants means that the ViewGroup will block its descendants from receiving focus.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:descendantFocusability="blocksDescendants"
android:id="#+id/linLyt"
>
in code:
yourListview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> list, View v, int pos, long id) {
// Your code for item click
}
});
Now for Button click listener in listview row: You can set the onClick() event in your custom adapter's getView() method.

Click item in listview does not work

When I click on any list item nothing happens, can someone please help or tell me where the problem is...?
Here is my Listview:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context=".defineBybeldbAlles">
<ListView
android:id="#+id/BybelHoofstukListView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:divider="#ff303030"
android:dividerHeight="1dp"
android:layout_marginTop="5dp"
android:choiceMode="singleChoice" />
</RelativeLayout>
Here is my Listview Item:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:focusable="false"
android:focusableInTouchMode="false"
android:descendantFocusability="blocksDescendants"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/customButtonLayout"
android:layout_height="50dp"
style="#android:style/Widget.Button"
android:focusable="false"
android:layout_width="200dp">
<! hoofstuk_id is hidden and is only for reference >
<TextView
android:text="id"
android:id="#+id/hoofstuk_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
>
</TextView>
<TextView
android:textColor="#000"
android:text="nommer"
android:layout_height="wrap_content"
android:id="#+id/custom_row_hoofstuktext"
android:layout_width="wrap_content"
android:layout_marginLeft="10dp">
</TextView>
</LinearLayout>
</LinearLayout>
Here is my OnItemclicklistener in the activity:
listviewHoofstuk.setOnItemClickListener(new AdapterView.OnItemClickListener(){
#Override
public void onItemClick (AdapterView<?> arg0, View view, int arg2, long arg3){
//on selecting a hoofstk
//BybelActivityVers will be launched to show verse inside
Intent hoofstukIntent = new Intent(BybelActivityHoofstuk.this,BybelActivityVers.class);
//send hoofstuk_id to VersActivity to get verse under that book
String hoofstuk_id_na_vers =((TextView)view.findViewById(R.id.hoofstuk_id)).getText().toString();
hoofstukIntent.putExtra("hoofstuk_id", hoofstuk_id_na_vers);
startActivity(hoofstukIntent);
}
});
Ive looked at a few other solutions but nothing works in my case, I added this code but it makes no difference when I use it or not:
android:focusable="false"
android:focusableInTouchMode="false"
android:descendantFocusability="blocksDescendants"
Yout list item is taking focus. Set below line in LinearLayout Tag in my Listview Item xml file
android:clickable="false"
Your intent will fire without taking focus and work properly I ahve checked it... Let me know once its works for you...
Use AdapterView to get adpater item views here you should use parent to find TextView
listviewHoofstuk.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//on selecting a hoofstk
//BybelActivityVers will be launched to show verse inside
Intent hoofstukIntent = new Intent(BybelActivityHoofstuk.this,BybelActivityVers.class);
//send hoofstuk_id to VersActivity to get verse under that book
String hoofstuk_id_na_vers =((TextView)parent.findViewById(R.id.hoofstuk_id)).getText().toString();
hoofstukIntent.putExtra("hoofstuk_id", hoofstuk_id_na_vers);
startActivity(hoofstukIntent);
}
});
Here is your solution:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context=".defineBybeldbAlles">
<ListView
android:id="#+id/BybelHoofstukListView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:divider="#ff303030"
android:dividerHeight="1dp"
android:layout_marginTop="5dp"/>
</RelativeLayout>
In your listview item you have to make this changes:
<LinearLayout
android:id="#+id/customButtonLayout"
android:layout_height="50dp"
style="#android:style/Widget.Button"
android:layout_width="200dp">
<! hoofstuk_id is hidden and is only for reference >
<TextView
android:text="id"
android:id="#+id/hoofstuk_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
>
</TextView>
<TextView
android:textColor="#000"
android:text="nommer"
android:layout_height="wrap_content"
android:id="#+id/custom_row_hoofstuktext"
android:layout_width="wrap_content"
android:layout_marginLeft="10dp">
</TextView>
</LinearLayout>
</LinearLayout>
This should solve your question if not just hit comment on this answer. After that you will start getting OnItemClick() event of listview.
I removed
android:focusable="false"
android:focusableInTouchMode="false"
android:descendantFocusability="blocksDescendants"
and then applied
android:clickable="false"
it did not work but after fiddling around I found that
android:clickable="false"
android:focusable="false"
in combination did the trick!
This was applied in the listview item just after LinearLayout.
I tested and can confirm it works with Gridview as well.

Android Listview OnItemClickListener sometimes not working

I have a small Android APP with a listview in it. Sometimes the listview does not react on my inputs. I can see that I touched on one item (it changes the color as I touched it), but the program does nothing.
This is my XML file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="false"
android:focusableInTouchMode="false" >
<TextView
android:id="#+id/textViewRowLable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:textSize="50sp" />
<TextView
android:id="#+id/textViewTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_toRightOf="#id/textViewRowLable"
android:gravity="right"
android:textSize="25sp" />
<TextView
android:id="#+id/textViewRemainingTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#id/textViewTime"
android:layout_toRightOf="#id/textViewRowLable"
android:gravity="right"
android:textSize="25sp" />
</RelativeLayout>
This is the listner:
.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(getApplicationContext(), "click", Toast.LENGTH_LONG).show();
}
});
Could someone give me a hint why it is not always working?
Thank you
Try using android:descendantFocusability="blocksDescendants" on your RelativeLayout
Also go through this tutorials:
Listview tips and tricks
I had a similar problem. Than I looked at the Android source and found the reason.
In the click handling, there is the following line
if (mDataChanged) return;
So the click is discarded, when the internal list data has changed.
I have updated the list very often. Reducing the update interval solved the problem nearly (after the change, only 1 of 100 clicks was not recognized)

ListView long click not working when a button is in list

I have a ListView with custom list adapter. It has OnItemClickListener and OnItemLongClickListner which used to work fine. After then, I had to put a button in the layout of list item and the item click and long click listener stopped working. Here is my sample code:
ListView lv=(ListView)findViewbyId(R.id.listview);
lv.setAdapter(listviewadapter);
lv.setOnItemLongClickListener(new OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view,int position, long id) {
// My code
}
});
This used to work fine before adding the button in the layout of list item:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="2dp"
>
<TextView
android:id="#+id/symbol_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2.5"
android:layout_gravity="left"
/>
<TextView
android:id="#+id/ltp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_weight="1"
/>
<TextView
android:id="#+id/change_in_perc"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_weight="1"
/>
<TextView
android:id="#+id/volume"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_weight="1"
/>
<ImageButton
android:id="#+id/chart"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_weight="0.5"
android:src="#drawable/charts"
android:contentDescription="Chart Link"
/>
</LinearLayout>
I tried changing inline listener to implementing onItemLongClickListener on activity but no success till now. Thanks.
Your image button is probably taking focus when you click on list item.
So Add this
android:descendantFocusability="blocksDescendants"
to your root element
http://developer.android.com/reference/android/view/ViewGroup.html#attr_android:descendantFocusability
android:descendantFocusability
Defines the relationship between the ViewGroup and its descendants when looking for a View to take focus.
Must be one of the following constant values.
Constant Value Description
beforeDescendants 0 The ViewGroup will get focus before any of its descendants.
afterDescendants 1 The ViewGroup will get focus only if none of its descendants want it.
blocksDescendants 2 The ViewGroup will block its descendants from receiving focus.
This corresponds to the global attribute resource symbol descendantFocusability.
did you set the android:longClickable="true" in the xml and the listview.setLongClickable(true); in the code ?

onItemClickListener and view not clickable

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content" android:orientation="horizontal"
android:layout_width="fill_parent"
android:clickable="false"
android:focusable="false">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:clickable="false"
android:focusable="false"
android:orientation="vertical" >
<TextView
android:id="#+id/MXname"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:clickable="false"
android:focusable="false"
android:gravity="left"
android:text="Slashdot"
android:textStyle="bold" />
<TextView
android:id="#+id/MXtnumber"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:clickable="false"
android:focusable="false"
android:gravity="left"
android:text="10 minutes ago" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="false"
android:focusable="false"
android:orientation="vertical"
android:gravity="right"
android:descendantFocusability="blocksDescendants">
<ImageView
android:id="#+id/MXdialer"
android:layout_width="35dp"
android:layout_height="fill_parent"
android:layout_weight="2"
android:clickable="true"
android:focusable="true"
android:gravity="right"
android:src="#drawable/lcall_button" />
</LinearLayout>
</LinearLayout>
I have a listview with the ROW xml listed above and below is the code from activity:
#Override
public void onItemClick(AdapterView<?> parent, View view, int position , long id)
{
Log.d("ItemClick","in the list"+ String.valueOf(view.getId()));
if (view==findViewById(R.id.MXdialer))
{
Toast.makeText(this, "Name and/or Phone number empty"+String.valueOf(id), Toast.LENGTH_LONG).show();
}
}
the Logcat does indicate the onitemClick being execuated but toast never works and view.getid() always returns -1. I have read the articles on onitemclicklisterner and have already made all the views as not focusable and not clickable but the still no go. Please suggest
view is the root layout of the clicked list item not the any child in the item layout. So the Toast will never show.
If you want click on any specific child view, set the onClickListener to that child, but then the OnItemClickListener will not be called. Either of the two will get called. The child views clikclistener takes priority.
for your if statement try this as not sure you can compare objects like the way your doing it.
int viewID=view.getId();
if(viewID== R.id.MXdialer)
Toast.makeText(this, "Name and/or Phone number empty"+String.valueOf(id), Toast.LENGTH_LONG).show();

Categories

Resources