Android:长按ExpandableListView的子视图?

时间:2010-02-28 23:11:27

标签: android

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

当我在setOnLongClickListener()的子视图中添加getChildView()时,整个子列表变得完全无法点击(尽管parentView.setOnChildClickListener()存在并且之前正在工作)。

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

5 个答案:

答案 0 :(得分:85)

我设法使用以下内容对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;
    }
});

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

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

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

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

答案 1 :(得分:40)

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

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

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

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

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

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

其次,创建上下文菜单:

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

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

答案 2 :(得分:32)

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

@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的这个解决方案很久以前了。我强烈建议立即转到 RecyclerView

答案 3 :(得分:12)

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

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

编辑:我现在看到autobot几乎没有正确的解决方案,除了getPackedPositionType上的id而不是packetPosition上的{{1}}

答案 4 :(得分:1)

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

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

    };

然后为可扩展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;
        }
    });

我们走了。