Android: long click on child views of ExpandableListView?

ExpandableListView has a setOnChildClickListener method, but does not have a setOnChild Long ClickListener method .

When I added setOnLongClickListener() to the child view in getChildView() , the whole count became completely invisible (despite the parentView.setOnChildClickListener() present and working before).

How to enable long clicks on child views?

+47
android
Feb 28 '10 at 23:11
source share
5 answers

I found the answer to Steve Oliver's blog: http://steveoliverc.wordpress.com/2009/10/16/context-menus-for-expandable-lists/

You should use onCreateContextMenu() instead of searching for setOnChildLongClickListener() . Here is information about Steve:

An extensible list supports context menus in much the same way as a standard list: add a listener for the context menu (when the user clicked on the list item for a long time). However, unlike the standard list view, you probably want to know if the user has selected a group (extensible item) or a list item of child items (subitems).

In addition, you can do nothing if the user tries to call the context menu for a group element. There may be times when you want to do something for all the children in the group, but in my Librarium application I wanted to ignore the elements of the group and present a context menu only for children.

First, you need to know when the context menu will be created so that you can determine if the user clicked on the group or child. If they clicked on a group, cancel the context menu. It also gives us the opportunity to get the text of the child, so that we can put it in the header of the context menu.

 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo; int type = ExpandableListView.getPackedPositionType(info.packedPosition); int group = ExpandableListView.getPackedPositionGroup(info.packedPosition); int child = ExpandableListView.getPackedPositionChild(info.packedPosition); // Only create a context menu for child items if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) { // Array created earlier when we built the expandable list String page =mListStringArray[group][child]; menu.setHeaderTitle(page); menu.add(0, MENU_READ, 0, "Read page"); menu.add(0, MENU_EDIT, 0, "Edit page"); menu.add(0, MENU_FAVORITE, 0, "Add page to favorites"); menu.add(0, MENU_EXPORT, 0, "Export page to file"); menu.add(0, MENU_DELETE, 1, "Delete page"); } } 

Secondly, create a context menu:

 public boolean onContextItemSelected(MenuItem menuItem) { ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) menuItem.getMenuInfo(); int groupPos = 0, childPos = 0; int type = ExpandableListView.getPackedPositionType(info.packedPosition); if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) { groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition); childPos = ExpandableListView.getPackedPositionChild(info.packedPosition); } // Pull values from the array we built when we created the list String author = mListStringArray[groupPos][0]; String page = mListStringArray[groupPos][childPos * 3 + 1]; rowId = Integer.parseInt(mListStringArray[groupPos][childPos * 3 + 3]); switch (menuItem.getItemId()) { case MENU_READ: readNote(rowId); return true; case MENU_EDIT: editNote(rowId); return true; // etc.. default: return super.onContextItemSelected(menuItem); } } 

Here it is. Now users can long click on an item in an expandable list and get a context menu if it is a child.

+40
Mar 01 '10 at 8:33
source share

I managed to get long clicks working on a child of the ExpandableListView using the following:

 getExpandableListView().setOnItemLongClickListener(new OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { if (ExpandableListView.getPackedPositionType(id) == ExpandableListView.PACKED_POSITION_TYPE_CHILD) { int groupPosition = ExpandableListView.getPackedPositionGroup(id); int childPosition = ExpandableListView.getPackedPositionChild(id); // You now have everything that you would as if this was an OnChildClickListener() // Add your logic here. // Return true as we are handling the event. return true; } return false; } }); 

It took a long time to figure out that the id argument in onItemLongClick was the packedPosition argument required by the getPackedPosition * methods, of course, not clear from the documentation.

Note. . For this solution, you need to override the getGroupId and getChildId() methods in your adapter

  @Override public long getGroupId(int groupPosition) { return groupPosition; } @Override public long getChildId(int groupPosition, int childPosition) { return childPosition; } 
+83
Nov 30 2018-11-11T00:
source share

I know that this answer may not be needed, but I have the same situation and I do not answer this problem. Therefore, I am sending a message in case someone needs it. Hope all of you guys don't mind.

 @Override public boolean onItemLongClick(AdapterView<?> parent, View childView, int flatPos, long id) { if (ExpandableListView.getPackedPositionType(id) == ExpandableListView.PACKED_POSITION_TYPE_CHILD) { final ExpandableListAdapter adapter = ((ExpandableListView) parent).getExpandableListAdapter(); long packedPos = ((ExpandableListView) parent).getExpandableListPosition(flatPos); int groupPosition = ExpandableListView.getPackedPositionGroup(packedPos); int childPosition = ExpandableListView.getPackedPositionChild(packedPos); // do whatever you want with groupPos and childPos here - I used these to get my object from list adapter. return false; } 

Edit This solution for Listview was a long time ago. I highly recommend switching to RecyclerView .

+30
May 8 '13 at 8:46 am
source share

I was looking for this answer, but not here gave the correct results.

Tomash's marked answer offers a completely different way. The answer from Nicholas is partially correct, but the use of "id" is incorrect.

That's right, work, answer: convert position to packedPosition and THEN! using this new packedPosition value to get the group and child identifiers. Check code below

  getExpandableListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { long packedPosition = getExpandableListView().getExpandableListPosition(position); if (ExpandableListView.getPackedPositionType(packedPosition) == ExpandableListView.PACKED_POSITION_TYPE_CHILD) { // get item ID's int groupPosition = ExpandableListView.getPackedPositionGroup(packedPosition); int childPosition = ExpandableListView.getPackedPositionChild(packedPosition); // handle data ... // return true as we are handling the event. return true; } return false; } }); 

EDIT : now I see that autobot has an almost correct solution, apart from testing getPackedPositionType on id and not on packetPosition

+12
Aug 31 '13 at 12:02
source share

I handle the problem with ur just set the ur item tag and use it, for example:

 adapter = new ExpandableListAdapter() { private String[] groups = { "Biceps", "Deltoids", "Hamstrings", "Lower Back","Quadriceps","Triceps","Wrist" }; private String[][] children = { { "Konsantra Dumbell curl", "Hammer curl", "Barbell Biceps Curl", "Prone Curl" }, { "Arnold Press", "Lateral Raise", "Dumbell Upright row", "Bar Military Press" }, { "Dead Lift", "Hack Squat","Zercher Squat","Seated Leg Flexion" }, { "Back Raise", "Superman" }, { "Back Squat", "Bulgarian Split Squat","Dumbell Lunge" }, { "Bench Dip", "French Press","Triceps Extension" }, { "Dumbell Wrist Curl "," Reverse Writst Curl"} }; public void unregisterDataSetObserver(DataSetObserver observer) { // TODO Auto-generated method stub } public void registerDataSetObserver(DataSetObserver observer) { // TODO Auto-generated method stub } public void onGroupExpanded(int groupPosition) { // TODO Auto-generated method stub } public void onGroupCollapsed(int groupPosition) { // TODO Auto-generated method stub } public boolean isEmpty() { // TODO Auto-generated method stub return false; } public boolean isChildSelectable(int groupPosition, int childPosition) { // TODO Auto-generated method stub return true; } public boolean hasStableIds() { // TODO Auto-generated method stub return true; } public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { TextView textView = getGenericView(); textView.setText(getGroup(groupPosition).toString()); textView.setTag((Object)getGroup(groupPosition).toString()+"G"); return textView; } public long getGroupId(int groupPosition) { // TODO Auto-generated method stub return groupPosition; } public int getGroupCount() { // TODO Auto-generated method stub return groups.length; } public Object getGroup(int groupPosition) { // TODO Auto-generated method stub return groups[groupPosition]; } public long getCombinedGroupId(long groupId) { // TODO Auto-generated method stub return 0; } public long getCombinedChildId(long groupId, long childId) { // TODO Auto-generated method stub return 0; } public int getChildrenCount(int groupPosition) { // TODO Auto-generated method stub return children[groupPosition].length; } public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { TextView textView = getGenericView(); textView.setText(getChild(groupPosition, childPosition).toString()); textView.setTag((Object)getChild(groupPosition, childPosition).toString()+"C"); return textView; } public long getChildId(int groupPosition, int childPosition) { // TODO Auto-generated method stub return childPosition; } public Object getChild(int groupPosition, int childPosition) { // TODO Auto-generated method stub return children[groupPosition][childPosition]; } public boolean areAllItemsEnabled() { // TODO Auto-generated method stub return false; } public TextView getGenericView() { // Layout parameters for the ExpandableListView AbsListView.LayoutParams lp = new AbsListView.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, 64); TextView textView = new TextView(expandXml.this); textView.setLayoutParams(lp); // Center the text vertically textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT); // Set the text starting position textView.setPadding(36, 0, 0, 0); return textView; } }; 

And then setOnItemLongClickListener for an extensible ListView.

 listView.setOnItemLongClickListener(new OnItemLongClickListener() { public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub String s=null; int childPosition =ExpandableListView.getPackedPositionChild(arg3); if(arg1.getTag()!=null){ Object o= arg1.getTag(); s = o.toString(); } Toast.makeText(expandXml.this ,s , Toast.LENGTH_SHORT).show(); return false; } }); 

Here we go.

+1
May 22 '12 at 21:35
source share



All Articles