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

前端 未结 5 692
星月不相逢
星月不相逢 2020-12-02 06:41

ExpandableListView has a setOnChildClickListener method, but lacks of setOnChildLongClickListener method.

When I added setOnL

相关标签:
5条回答
  • 2020-12-02 07:15

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

    Marked answer from tomash suggest completely different way. Answer from Nicholas is partially correct, but using 'id' is incorrect.

    Correct, working, answer is: convert position parameter to packedPosition and THEN! using this new packedPosition value to obtain group and child ID's. 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: I now see that autobot has almost correct solution, except testing getPackedPositionType on id and not on packetPosition

    0 讨论(0)
  • 2020-12-02 07:16

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

    Edit This solution for Listview was long time ago. I highly recommend to move to RecyclerView now.

    0 讨论(0)
  • 2020-12-02 07:24

    I found an answer on Steve Oliver's blog here: 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:

    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.

    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.

    0 讨论(0)
  • 2020-12-02 07:27

    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(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.

    0 讨论(0)
  • 2020-12-02 07:32

    I managed to get long clicks working on an ExpandableListView child item, 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 ages to figure out that the id argument in onItemLongClick was the packedPosition argument required by getPackedPosition* methods, certainly not clear from the documentation.

    Note: For this solution to work 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;
       }
    
    0 讨论(0)
提交回复
热议问题