Как я могу зафиксировать долгое нажатие на пункт меню?

У меня типичное меню, и я хочу установить 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;
        }

    });

person adneal    schedule 03.10.2011    source источник


Ответы (3)


Я смог сделать это, просто используя setActionView в menuItem. Вы можете выполнить эту процедуру, если она поможет.

    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);
    }
person Krishna Kishore Andhavarapu    schedule 26.02.2016

Используйте метод findItem на Menu, чтобы получить ваши просмотры, и установите свой долгий прослушиватель кликов для каждого просмотра.

person Christopher Perry    schedule 03.10.2011
comment
нет, в объекте Menu есть метод с именем findItem. Используйте это, чтобы получить представление, и установите прослушиватель длительного щелчка на просмотре. - person Christopher Perry; 04.10.2011
comment
Я получаю ту же ошибку. Этот OnLongClickListener не определен в MenuItem. Можете ли вы предложить еще помощь? - person adneal; 04.10.2011
comment
Извините, вам нужен дескриптор View. Попробуйте getActionView () в пункте меню. - person Christopher Perry; 04.10.2011
comment
Я все еще не совсем разбираюсь в этом, но спасибо, что помогли мне. - person adneal; 04.10.2011
comment
Я продолжал получать ту же неопределенную ошибку. Я понимаю, что мне делать, но мне нужно найти, где я все испортил. Я получу это. - person adneal; 05.10.2011
comment
И getActionView (), конечно, возвращает null, потому что мой пункт меню НЕ ИМЕЕТ вида действия. Вопрос OP заключается в том, как зафиксировать долгое нажатие на MenuItem, а не на просмотре действия пункта меню. - person Robin Davies; 20.11.2015
comment
В Android вы прикрепляете прослушиватели кликов к представлениям. Нет других интерактивных элементов, вы не можете щелкать или долго нажимать и т. Д. На чем-либо, кроме какого-то вида. - person Christopher Perry; 24.11.2015

Это неправильный подход, он нарушает весь поток, но вот, пожалуйста:

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

Пункты меню в переполнении WILL NOT следует учитывать.

person Nikola Despotoski    schedule 26.08.2013