在列表视图上进行长按事件后创建菜单

71

我有一个连接到数据库的列表视图,显示所有条目。如果用户长按列表视图(数据库条目),我希望出现一个菜单,显示编辑或删除该条目的选项。如何实现?

迄今为止,我尝试使用onItemLongClick监听器和其中的toast,在其中显示长按的视图的ID。

@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
        int position, long id) {

    String res = Long.toString(id);
     Toast toast = Toast.makeText(this, res, Toast.LENGTH_SHORT);
     toast.show();

    return true;
}
7个回答

119

首先,您需要在列表视图上注册您的上下文菜单。

lv = (ListView) findViewById(R.id.list_view);
registerForContextMenu(lv);

然后,只需覆盖活动方法即可。

/**
 * MENU
 */

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
      super.onCreateContextMenu(menu, v, menuInfo);
      if (v.getId()==R.id.list_view) {
          MenuInflater inflater = getMenuInflater();
          inflater.inflate(R.menu.menu_list, menu);
      }
}

@Override
public boolean onContextItemSelected(MenuItem item) {
      AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
      switch(item.getItemId()) {
         case R.id.add:
         // add stuff here
            return true;
          case R.id.edit:
            // edit stuff here
                return true;
          case R.id.delete:
        // remove stuff here
                return true;
          default:
                return super.onContextItemSelected(item);
      }
}

这是一个menu_list.xml文件的示例(您需要将该文件放置在res/menu文件夹中)。

<?xml version="1.0" encoding="utf-8"?>
<menu
  xmlns:android="http://schemas.android.com/apk/res/android">

       <item android:id="@+id/add"
              android:icon="@android:drawable/ic_menu_add"
              android:title="@string/menu_add" />

      <item android:id="@+id/edit"
              android:icon="@android:drawable/ic_menu_edit"
              android:title="@string/menu_edit" />

       <item android:id="@+id/delete"
            android:icon="@android:drawable/my_icon_delete"
             android:title="@string/menu_delete" />

</menu>

希望它能够帮到你。


谢谢,它可以工作,但是我怎么知道在列表中哪个项目被长按了?有ID吗? - Enriqe
17
好的,我找到了。您可以按以下方式获取长按列表项的ID或位置:((AdapterView.AdapterContextMenuInfo)menuInfo).id ((AdapterView.AdapterContextMenuInfo)menuInfo).position 请注意,这些代码片段需要在上下文中使用,并且需要先定义menuInfo变量。 - Enriqe
switch语句不再起作用,因为像R.id.add这样的值不再生成为常量。因此,我需要用if-else语句替换switch! - mvsagar
3
很好的例子,但上下文菜单不支持图标。 - dave
1
嘿,你已经为菜单设置了图标,但是菜单中没有图标。为什么?我该如何显示图标? - Sharikov Vladislav
我在我的DialogFragment中尝试了这个,上下文菜单被显示出来了,但是在点击菜单项后onContextItemSelected没有被调用。为什么?我使用的是Android 6.0。 - Taufik Nur Rahmanda

51

你可以使用onItemLongClick的替代方式。

public void onCreateContextMenu(final ContextMenu menu, 
                    final View v, final ContextMenuInfo menuInfo) {
 ...
}

你可以在那里设置编辑和删除等选项。

从上下文菜单中选择的项目的操作可以在此处处理。

public boolean onContextItemSelected(final MenuItem item)

有关上下文菜单的更多信息,请参见此处

要查看逐步教程,请访问此处

编辑 第二个链接已经失效,因为它相当古老。 但是我想您可以参考其他得到高票答案中的一个来查看涉及到的所有步骤。


2
我尝试使用oncreateContextMenu,目前为止它对我有效。谢谢。 - Eriz
它很老了。我放置时还能工作。谢谢指出。 - 7bluephoenix

6

另一种方法:

//Deleted individual cart items
    //on list view cell long press
    cartItemList.setOnItemLongClickListener (new OnItemLongClickListener() {
          @SuppressWarnings("rawtypes")
        public boolean onItemLongClick(AdapterView parent, View view, final int position, long id) {
              final CharSequence[] items = { "Delete" };

                AlertDialog.Builder builder = new AlertDialog.Builder(context);

                builder.setTitle("Action:");
                builder.setItems(items, new DialogInterface.OnClickListener() {

                    public void onClick(DialogInterface dialog, int item) {
                        cart = cartList.get(position);
                        db.removeProductFromCart(context, cart);

                        new AlertDialog.Builder(context)
                        .setTitle(getString(R.string.success))
                        .setMessage(getString(R.string.item_removed))
                        .setPositiveButton("Done", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) { 
                                Intent intent = new Intent(CartDetailsActivity.this, HomeScreen.class);
                                startActivity(intent);
                            }
                         })
                         .show();

                    }

                });

                AlertDialog alert = builder.create();

                alert.show();
            //do your stuff here
              return false;
          }
        });

2

如果您可以使用选项菜单,这是一种不错的解决方案(仅需1行!),并且是上下文菜单所需的所有设置的替代方法。 - Gene Bo

1

**

注册完列表视图上下文菜单后,需要像这样重写onCreateContextMenu方法:
@Override
    public void onCreateContextMenu(ContextMenu menu,View v, ContextMenu.ContextMenuInfo menuInfo){
        if (v.getId() == R.id.listView){
            AdapterView.AdapterContextMenuInfo info =(AdapterView.AdapterContextMenuInfo)menuInfo;
            MenuItem mnu1=menu.add(0,0,0,"Delete");
            MenuItem mnu2=menu.add(0,1,1,"Share");
        }
    }

然后为每个可选项编写代码

 @Override
    public boolean onContextItemSelected(MenuItem menuItem){
        AdapterView.AdapterContextMenuInfo info=(AdapterView.AdapterContextMenuInfo)menuItem.getMenuInfo();
        switch (menuItem.getItemId()) {
            case 0:
                Toast.makeText(this, "Delete Selected", Toast.LENGTH_LONG).show();
                break;
            case 1:
                Toast.makeText(this, "Share Selected", Toast.LENGTH_LONG).show();
                break;

            default:
                break;

        }
        return true;
    }

0
对于那些仍在苦苦挣扎的人,这里有两种方法。
registerForContextMenu(list);
unregisterForContextMenu(list);

确保您选择第一个。


0
使用registerForContextMenu()将上下文菜单链接到任何View后继。 要访问所选ListItem数据,只需简单地使用AdapterView.AdapterContextMenuInfo。 例如:
@Override
public boolean onContextItemSelected(MenuItem item) {
    AdapterView.AdapterContextMenuInfo menuinfo = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
    long selectid = menuinfo.id; //_id from database in this case
    int selectpos = menuinfo.position; //position in the adapter
    switch (item.getItemId()) {
    case 1:
        doSomething(selectid);
    break;
    case 2:
        doSomethingElse(selectpos);
    }
    return super.onContextItemSelected(item);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接