如何从 PopupMenu onMenuItemClick 获取 RecyclerView 位置

How to get RecyclerView position from PopupMenu onMenuItemClick

使用 RecylcerView,我试图为列表中的每个项目设置一个弹出菜单,类似于:

创建弹出菜单很简单,但是如何获取在 onMenuItemClicked 中单击的项目的位置?

public class Activity extends AppCompatActivity implements PopupMenu.OnMenuItemClickListener {

    public void showPopupMenu(View v) {
        PopupMenu popupMenu = new PopupMenu(this, v);
        MenuInflater inflater = popupMenu.getMenuInflater();
        inflater.inflate(R.menu.edit_delete_menu, popupMenu.getMenu());
        popupMenu.show();
    }

    @Override
    public boolean onMenuItemClick(MenuItem item) {

        //get position here from RecyclerView here?

        switch (item.getItemId()) {
            case R.id.edit:
            //Do position specific action
            break;
            case R.id.delete:
                //Do position specific action
                break;
        }
        return false;
    }


}

首先,在您显示的代码片段中,它与可用图像不相关。

请提供您的 onBindViewHolder 代码。那是应该设置菜单项的点击侦听器的地方。

好吧,所以我(令人惊讶地)设法在这里回答了我自己的问题。

为了使用 PopupMenuonMenuItemClicked 中的 RecylcerView 适配器获取位置,我创建了 PopupMenu.

的自定义实现

这样做可以在使用 PopupMenu 时提供更大的灵活性,例如 displaying icons in your menus

查看 Google 的 PopupMenu 源代码,并创建您自己的源代码,例如 MyPopupMenu 完全相同,但您可以修改某些实例class可以做到。

为了完成我的问题,我在 RecyclerView.Adapter 中的“更多”按钮中添加了一个 OnClickListener。单击时,按钮调用一个接口方法,该方法同时传递按钮视图和适配器的当前位置。

MyPopupMenu的自定义实现中,为每个构造函数添加一个int值的变量要求。还要在MyPopupMenu.

中的接口方法onMenuItemClick(MenuItem item, int position)中添加int position

最后,assemble在activityclass.

public class MyActivity extends AppCompatActivity implements MyAdapter.OnItemEventListener, PopupMenu.OnMenuItemClickListener {

    @Override
    public void onMoreClicked(View v, int position) {
        MyPopupMenu popupMenu = new MyPopupMenu(this, v, position);
        MenuInflater inflater = popupMenu.getMenuInflater();
        inflater.inflate(R.menu.edit_delete_menu, popupMenu.getMenu());
        popupMenu.setOnMenuItemClickListener(this);
        popupMenu.show();
    }

    @Override
    public boolean onMenuItemClick(MenuItem item, int position) {
        switch (item.getItemId()) {
            case R.id.edit:
                //Do position specific action with int position
                break;
            case R.id.delete:
                //Do position specific action with int position
                break;
        }
        return false;
    }
}

class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    private final OnItemEventListener onItemEventListener;

    static class ViewHolder extends RecyclerView.ViewHolder {
        ImageButton more;

        ViewHolder(View v) {
            super(v);
            more = (ImageButton) v.findViewById(R.id.list_item_more_button);
        }
    }

    public NewGameAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
        final ViewHolder viewHolder = new ViewHolder(v);

        viewHolder.more.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                onItemEventListener.onMoreClicked(viewHolder.more, viewHolder.getAdapterPosition());
            }
        });

        return viewHolder;
    }

    interface OnItemEventListener {
        void onMoreClicked(View v, int position);
    }
}

让我知道你们的想法!

您好亲爱的,您需要在适配器中使用这种方式

  @Override
    public void onBindViewHolder(@NonNull final RecentPlayedAdapter.MyViewHolder holder, final int position) {
        holder.menudotes.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
PopupMenu popupMenu=new PopupMenu(context, holder.menudotes, Gravity.START);
                    popupMenu.getMenuInflater().inflate(R.menu.popupmenu1,popupMenu.getMenu());
                    popupMenu.show();
                    popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                        @Override
                        public boolean onMenuItemClick(MenuItem item) {
                            switch (item.getItemId()) {
                                case R.id.download:
                                    Toast.makeText(context, "Download", Toast.LENGTH_SHORT).show();
                                    //Do position specific action with int position
                                    break;
                                case R.id.playlist:
                                    //Do position specific action with int position
                                    Toast.makeText(context, "Playlist", Toast.LENGTH_SHORT).show();

                                    break;
                                case R.id.share:
                                    //Do position specific action with int position
                                    Toast.makeText(context, "Share", Toast.LENGTH_SHORT).show();


                                    break;
                            }
                            return true;
                        }
                    });
    }
        });
    }