为RecyclerView-Item创建选项菜单 [英] Create Options Menu for RecyclerView-Item

查看:212
本文介绍了为RecyclerView-Item创建选项菜单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何创建选项菜单,如以下屏幕截图所示:

How do I create an Options Menu like in the following Screenshot:

在单击RecyclerView项目的更多"图标后,应该会打开选项"菜单!

The Options Menu should be opened afther clicking on the "More"-Icon of a RecyclerView Item!

我的尝试是这样的:

@Override
public void onBindViewHolder(Holder holder, int position) {
    holder.txvSongTitle.setText(sSongs[position].getTitle());
    holder.txvSongInfo.setText(sSongs[position].getAlbum() + " - " + sSongs[position].getArtist());

holder.btnMore.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(mContext, "More...", Toast.LENGTH_SHORT).show();
        }
    });
}

但这会导致问题,因为如果我触摸RecyclerView项的更多"按钮,则会单击整个项.

But this causes problems because the full item is clicked if I touch on the RecyclerView Item More-Button...

这是我的RecyclerViewOnTouchListener:

Here's my RecyclerViewOnTouchListener:

public class RecyclerViewOnTouchListener implements RecyclerView.OnItemTouchListener {
    private GestureDetector mGestureDetector;
    private OnTouchCallback mOnTouchCallback;

    public RecyclerViewOnTouchListener(Context context, final RecyclerView recyclerView, final OnTouchCallback onTouchCallback) {
        mOnTouchCallback = onTouchCallback;

        mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }

            @Override
            public void onLongPress(MotionEvent e) {
                View child = recyclerView.findChildViewUnder(e.getX(), e.getY());

                if (child != null && onTouchCallback != null) {
                    onTouchCallback.onLongClick(child, recyclerView.getChildLayoutPosition(child));
                }

                super.onLongPress(e);
            }
        });
    }

    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        View child = rv.findChildViewUnder(e.getX(), e.getY());

        if (child != null && mOnTouchCallback != null && mGestureDetector.onTouchEvent(e)) {
            mOnTouchCallback.onClick(child, rv.getChildLayoutPosition(child));
        }

        return false;
    }

    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {

    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }

    public interface OnTouchCallback {
        void onClick(View view, int position);
        void onLongClick(View view, int position);
    }
}

我找不到任何类似的问题,所以希望您能为我提供帮助!

I wasn't able to find any similar problem so I hope you can help me!

推荐答案

我发现唯一的菜单,看起来像上面的菜单是PopupMenu.

I found out that the only Menu, that looks like the Menu above is the PopupMenu.

所以在onClick中:

@Override
public void onClick(View view, int position, MotionEvent e) {
    ImageButton btnMore = (ImageButton) view.findViewById(R.id.item_song_btnMore);

    if (RecyclerViewOnTouchListener.isViewClicked(btnMore, e)) {
        PopupMenu popupMenu = new PopupMenu(view.getContext(), btnMore);

        getActivity().getMenuInflater().inflate(R.menu.menu_song, popupMenu.getMenu());

        popupMenu.show();

        //The following is only needed if you want to force a horizontal offset like margin_right to the PopupMenu
        try {
            Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
            fMenuHelper.setAccessible(true);
            Object oMenuHelper = fMenuHelper.get(popupMenu);

            Class[] argTypes = new Class[] {int.class};

            Field fListPopup = oMenuHelper.getClass().getDeclaredField("mPopup");
            fListPopup.setAccessible(true);
            Object oListPopup = fListPopup.get(oMenuHelper);
            Class clListPopup = oListPopup.getClass();

            int iWidth = (int) clListPopup.getDeclaredMethod("getWidth").invoke(oListPopup);

            clListPopup.getDeclaredMethod("setHorizontalOffset", argTypes).invoke(oListPopup, -iWidth);

            clListPopup.getDeclaredMethod("show").invoke(oListPopup);
        }
        catch (NoSuchFieldException nsfe) {
            nsfe.printStackTrace();
        }
        catch (NoSuchMethodException nsme) {
            nsme.printStackTrace();
        }
        catch (InvocationTargetException ite) {
            ite.printStackTrace();
        }
        catch (IllegalAccessException iae) {
            iae.printStackTrace();
        }
    }
    else {
        MusicPlayer.playSong(position);
    }
}

您必须使onClick-Method传递MotionEvent,最后在Re​​cyclerViewOnTouchListener中实现方法isViewClicked:

You have to make your onClick-Method pass the MotionEvent and finally implement the Method isViewClicked in your RecyclerViewOnTouchListener:

public static boolean isViewClicked(View view, MotionEvent e) {
    Rect rect = new Rect();

    view.getGlobalVisibleRect(rect);

    return rect.contains((int) e.getRawX(), (int) e.getRawY());
}

这篇关于为RecyclerView-Item创建选项菜单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆