如何在菜单项上捕获长按事件?

3

我有一个典型的菜单,想要为其中一个项目设置 onLongClickListener 。换句话说,我希望该项目执行其正常的 onOptionsItemSelected 函数,以及长按函数。

    MenuItem item;
    item = menu.findItem(android.R.id.home);

item.setOnLongClickListener(new OnLongClickListener() {
        public boolean onLongClick(View v) {
            Context context = getApplicationContext();
            CharSequence text = "Long Press";
            int duration = Toast.LENGTH_SHORT;

            Toast toast = Toast.makeText(context, text, duration);
            toast.show();
            return true;
        }

    });
3个回答

1

我能够通过在menuItem上使用setActionView来完成这个操作。如果有帮助,您可以按照以下步骤进行。

    for(int i = 0; i < menu.size(); i++){
        View v = new View(this);
        v.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                //Your longclick listener callback logic goes here
                return false;
            }

        });
        menu.getItem(i).setActionView(v);
    }

0

这种方法不正确,它会干扰整个流程,但是你可以试试:

    private interface OnMenuItemLongClickListener{
        boolean onMenuItemLongClik(MenuItem m);
    }
    private void getMenuItemsView(Activity a, final Menu m, final OnMenuItemLongClickListener listener) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException{
        View homeButton = a.findViewById(android.R.id.home);
        ViewParent parentOfHome = homeButton.getParent().getParent(); //ActionBarView is parent of home ImageView, see layout file in sources

        if (!parentOfHome.getClass().getName().contains("ActionBarView")) {
            parentOfHome = parentOfHome.getParent(); 
            Class absAbv = parentOfHome.getClass().getSuperclass(); //ActionBarView -> AbsActionBarView class
            Field actionMenuPresenterField = absAbv.getDeclaredField("mActionMenuPresenter");
            actionMenuPresenterField.setAccessible(true);
            Object actionMenuPresenter = actionMenuPresenterField.get(parentOfHome);
            Field actionMenuViewField = actionMenuPresenter.getClass().getSuperclass().getDeclaredField("mMenuView");
            actionMenuViewField.setAccessible(true);
            Object actionMenuView = actionMenuViewField.get(actionMenuPresenter);
            Field childrenField= actionMenuView.getClass().getSuperclass().getSuperclass().getDeclaredField("mChildren");
            childrenField.setAccessible(true);
            Field menuField =actionMenuPresenter.getClass().getSuperclass().getDeclaredField("mMenu");
            menuField.setAccessible(true);
            Object menu = menuField.get(actionMenuPresenter);
            Object[] menuItemsAsViews = (Object[])childrenField.get(actionMenuView);
            View.OnLongClickListener longListener = new View.OnLongClickListener() {

                @Override
                public boolean onLongClick(View v) {

                    return listener.onMenuItemLongClik(m.findItem(v.getId()));
                }
            };
            for(Object menuView:menuItemsAsViews ){
                View v = (View)menuView;
                v.setOnLongClickListener(longListener);
            }


    }
 }

使用方法:

@Override
public boolean onPrepareOptionsMenu(final Menu menu) {
        new Handler().postDelayed(new Runnable(){

            @Override
            public void run() {
            getMenuItemsViews(MainActivity.this, menu);
            }}, 100); //must be called after the menu views are generated, otherwise NPE.
    return super.onPrepareOptionsMenu(menu);
}

溢出菜单中的不会被考虑。


0
使用Menu上的findItem方法获取您的视图,并在每个视图上设置长按监听器。

不,Menu对象上有一个名为findItem的方法。使用它来获取一个View,并在该View上设置长按监听器。 - Christopher Perry
我得到了相同的错误。在 MenuItem 中,OnLongClickListener 未定义。你能提供更多帮助吗? - adneal
抱歉,您需要一个视图句柄。请尝试在菜单项上调用getActionView()方法。 - Christopher Perry
1
当然,getActionView()返回null,因为我的菜单项没有动作视图。OP的问题是如何捕获MenuItem上的长按事件,而不是菜单项的操作视图。 - Robin Davies
在Android中,您可以将点击监听器附加到视图上。除了某种类型的视图之外,没有其他可点击的元素,您无法单击、长按等任何东西。 - Christopher Perry
显示剩余2条评论

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