Android:长按一下ExpandableListView的子视图?

ExpandableListView有一个setOnChildClickListener方法,但缺lesssetOnChildClickListener方法。

当我在getChildView()子视图中添加setOnLongClickListener()时,整个子列表变得完全parentView.setOnChildClickListener()点击(尽pipe之前存在parentView.setOnChildClickListener() )。

如何启用长时间点击子视图?

我设法得到一个ExpandableListView子项目,使用下面的长按:

 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; } }); 

花了很长时间才发现packedPosition中的id参数是getPackedPosition *方法所要求的packedPosition参数,当然在文档中不是很清楚。

注意:要使此解决scheme起作用,您需要覆盖适配器中的getGroupIdgetChildId()方法

  @Override public long getGroupId(int groupPosition) { return groupPosition; } @Override public long getChildId(int groupPosition, int childPosition) { return childPosition; } 

我在这里find了Steve Oliver的博客上的答案: http : //steveoliverc.wordpress.com/2009/10/16/context-menus-for-expandable-lists/

您应该使用onCreateContextMenu()而不是查找setOnChildLongClickListener() 。 这是史蒂夫的信息:

可扩展列表支持上下文菜单,几乎与标准列表相同:添加上下文菜单的监听器(当用户长按列表项时)。 但是,与标准列表视图不同,您可能想知道用户是select了一个组(可展开项目)还是一个子项目(子项目)。

此外,如果用户尝试在组项目上调出上下文菜单,则可能不想执行任何操作。 可能有些情况下,你会想要为一个组下的所有孩子做些什么,但是在我的Librarium应用程序中,我想忽略组项目,并仅为儿童提供上下文菜单。

首先,您需要知道上下文菜单何时将被创build,以便您可以识别用户是按下了一个组还是一个孩子。 如果他们按下一个组,则取消上下文菜单。 这也使我们有机会获取子项的文本,以便我们可以将它放到上下文菜单的标题中。

 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”); } } 

其次,创build上下文菜单:

 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); } } 

而已。 现在,用户可以长按可扩展列表中的项目,如果是子项目,则可以获取上下文菜单。

我知道这个答案可能是没有必要的,但是我有类似的情况,而且这些答案都没有解决我的问题。 所以我张贴我的情况下有人可能需要它。 希望你们不介意。

 @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; } 

编辑 Listview的这个解决scheme很久以前。 我强烈build议现在转移到RecyclerView

我正在寻找这个答案,但这里没有给出正确的结果。

从tomash标记的答案表明完全不同的方式。 Nicholas的回答是部分正确的,但使用'id'是不正确的。

正确的,工作,答案是:将position参数转换为packedPosition ,然后! 使用这个新的packedPosition值来获得组和子ID。 检查下面的代码

  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; } }); 

编辑 :我现在看到, 自动机器人有几乎正确的解决scheme,除了testinggetPackedPositionType id和不packetPosition

我处理你的问题。 只需设置一个标签你的项目,并使用它,如下所示:

 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; } }; 

然后setOnItemLongClickListener为Expandable 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; } }); 

开始了。