Android:长按 ExpandableListView 的子视图?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2353074/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:30:31  来源:igfitidea点击:

Android: long click on the child views of a ExpandableListView?

android

提问by tomash

ExpandableListView has a setOnChildClickListener method, but lacks of setOnChildLongClickListenermethod.

ExpandableListView 有一个 setOnChildClickListener 方法,但缺少setOnChildLong ClickListener方法。

When I added setOnLongClickListener()on child view in getChildView(), whole sublist became completely unclickable (despite of parentView.setOnChildClickListener()present and working before).

当我在 中添加setOnLongClickListener()子视图时getChildView(),整个子列表变得完全无法点击(尽管parentView.setOnChildClickListener()现在和以前工作过)。

How can I enable long clicks on child views?

如何在子视图上启用长按?

采纳答案by tomash

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

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

You should use onCreateContextMenu()instead of looking for setOnChildLongClickListener(). Here is Steve's info:

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

An expandable list supports context menus in pretty much the same way that a standard list does: add a listener for the context menu (when the user has long-pressed on a list item). Unlike a standard list view, however, you probably want to know whether the user has selected a group (expandable item) or a child (sub-item) list item.

可扩展列表以与标准列表几乎相同的方式支持上下文菜单:为上下文菜单添加一个侦听器(当用户长按列表项时)。然而,与标准列表视图不同,您可能想知道用户是选择了组(可扩展项)还是子(子项)列表项。

Furthermore, you might not want to do anything if the user tries to bring up a context menu on a group item. There might be cases where you would want to do something to all of the children under a group, but in my Librarium application, I wanted to ignore group items and present the context menu only for children.

此外,如果用户尝试在组项目上调出上下文菜单,您可能不想做任何事情。在某些情况下,您可能希望对某个组下的所有孩子执行某些操作,但在我的 Librarium 应用程序中,我想忽略组项目并仅为孩子显示上下文菜单。

First, you need to know when the context menu is going to be created so that you can identify whether the user pressed on a group or a child. If they pressed on a group, then cancel the context menu. This also gives us a chance to get the text of the child item, so that we can put it into 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 the 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);
  }
}

That's it. Now users can long-press on an item in an expandable list, and get the context menu if it's a child item.

就是这样。现在,用户可以长按可扩展列表中的项目,如果它是子项目,则可以获得上下文菜单。

回答by Nicholas Harlen

I managed to get long clicks working on an ExpandableListViewchild item, using the following:

我设法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;
    }
});

It took ages to figure out that the id argument in onItemLongClick was the packedPositionargument required by getPackedPosition* methods, certainly not clear from the documentation.

花了很长时间才弄清楚 onItemLongClick 中的 id 参数是* 方法packedPosition所需的参数getPackedPosition,当然文档中没有明确说明。

Note:For this solution to work you need to override the getGroupIdand getChildId()methods in your adapter

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

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

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

回答by toantran

I know this answer may be no need, but I have similar situation and non of these answer solve my problem. So I post mine in case someone may need it. Hope all 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;
                }

EditThis solution for Listview was long time ago. I highly recommend to move to RecyclerViewnow.

编辑Listview 的这个解决方案是很久以前的。我强烈建议现在转向RecyclerView

回答by Menion Asamm

I was searching for this answer, but non here gave correct results.

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

Marked answer from tomashsuggest completely different way. Answer from Nicholasis partially correct, but using 'id' is incorrect.

来自tomash 的标记答案暗示了完全不同的方式。Nicholas 的回答部分正确,但使用 'id' 是不正确的。

Correct, working, answer is: convert positionparameter to packedPositionand THEN! using this new packedPositionvalue to obtain group and child ID's. Check code below

正确,有效,答案是:将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;
        }
    });

EDIT: I now see that autobothas almost correct solution, except testing getPackedPositionTypeon idand not on packetPosition

编辑:我现在看到汽车人几乎正确的解决方案,除了测试getPackedPositionTypeid,而不是packetPosition

回答by Ycaner

I handle ur problem. just set a tag ur item and use it ,like this:

我处理你的问题。只需设置一个标签你的项目并使用它,就像这样:

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 Expandable ListView.

然后为可扩展的 ListView setOnItemLongClickListener。

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.

开始了。