(Устаревший) Фрагмент onOptionsItemSelected не вызывается

EDIT: Этот вопрос касался устаревшей панели действий sherlock. Теперь нужно использовать библиотеку поддержки Android

Я добавил параметр меню панели действий, который называется share для моего fragment, который появляется, но событие выбора не попадает

Я добавляю его так:

@Override
public void onCreateOptionsMenu (Menu menu, MenuInflater inflater) {
    MenuItem item = menu.add(0, 7,0, R.string.share);
    item.setIcon(R.drawable.social_share).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
}

Попытка захватить его как в fragment, так и в fragment activity как

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {
        case 7:
            Intent share = new Intent(Intent.ACTION_SEND);
            share.setType("text/plain");
            share.putExtra(Intent.EXTRA_TEXT, "I'm being sent!!");
            startActivity(Intent.createChooser(share, "Share Text"));
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

и я setHasOptionsMenu(true); в onCreate().

Ответ 1

Изменить для использования sherlock для панели действий

Мне пришлось использовать

public boolean onMenuItemSelected(int featureId, MenuItem item) {

в основном действии для захвата пункта меню

Ответ 2

Те же проблемы со мной произошли:

onMenuItemВыбранные события не вызывались во Фрагменте

Поиск google не может найти решение и добавить метод onMenuItemSelected в FragmentActivity не решает его.

Наконец, разрешите его, следуя ссылке http://developer.android.com/guide/topics/ui/actionbar.html

Примечание. Если вы добавили элемент меню из фрагмента, через обратный вызов класса Fragment onCreateOptionsMenu, система вызывает соответствующий метод onOptionsItemSelected() для этого фрагмента, когда пользователь выбирает один из элементов фрагмента. Тем не менее, эта функция получает возможность сначала обработать событие, поэтому система вызывает onOptionsItemSelected() в активности перед вызовом того же обратного вызова для фрагмента.

Это означает, что только если у вас нет этого обработчика элементов в onOptionsItemSelected() для активности, вызывается onOptionsItemSelected() на фрагменте.

Код в следующем порядке ----- Удалите обработчик для R.action.add в FragmentActivity):

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {
        case android.R.id.home:
            popBackStack();             
            return true;        
        case R.id.action_search:
            searchAction();
            return true;
        case R.id.action_logout:
            userLogout();
            return true;
        //case R.id.action_add:
            //return true;    
        default:
            return super.onOptionsItemSelected(item);
    }   
}

И обработчик для R.action.add на фрагменте выглядит следующим образом:

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    Log.d("onOptionsItemSelected","yes");
    switch (item.getItemId()) {
        case R.id.action_add:
            add();
            return true;    
        default:
            return super.onOptionsItemSelected(item);
    }
}

Наконец, не забудьте добавить

    setHasOptionsMenu(true);

в методе onCreate в фрагменте

Ответ 3

У меня была такая же проблема, но я думаю, что лучше подвести итог и ввести последний шаг, чтобы заставить ее работать:

  • Добавьте метод setHasOptionsMenu(true) в метод Fragment onCreate(Bundle savedInstanceState).

  • Переопределить onCreateOptionsMenu(Menu menu, MenuInflater inflater) (если вы хотите сделать что-то другое в своем меню фрагментов) и onOptionsItemSelected(MenuItem item) в вашем фрагменте.

  • Внутри вашей операции onOptionsItemSelected(MenuItem item) убедитесь, что вы возвращаете false, когда действие элемента меню будет реализовано в методе Fragment onOptionsItemSelected(MenuItem item).

Пример:

Деятельность

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getSupportMenuInflater();
    inflater.inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.activity_menu_item:
        // Do Activity menu item stuff here
        return true;
    case R.id.fragment_menu_item:
        // Not implemented here
        return false;
    default:
        break;
    }

    return false;
}

Фрагмент

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
    ....
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    // Do something that differs the Activity menu here
    super.onCreateOptionsMenu(menu, inflater);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.activity_menu_item:
        // Not implemented here
        return false;
    case R.id.fragment_menu_item:
        // Do Fragment menu item stuff here
        return true;
    default:
        break;
    }

    return false;
}

Ответ 4

Я заметил, что решение, которое люди дали вам, это реализовать код для вашего объекта menue в активности, а не фрагмент. Я думаю, что это будет выглядеть намного более гармонизированным, если бы вы реализовали код в фрагменте, а не активность, потому что, по-моему, это выглядит лучше. Для этого сделайте следующее:

активность

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        getMenuInflater().inflate(R.menu.menu, menu);      
        return true;
    }

 @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {            
        switch (item.getItemId())
        {
            case R.id.SomeIDInTheMenueOfTheActivity:
            {
               //something();
                break;
            }
            default:
             //do something default and add the code under : 
             return super.onOptionsItemSelected(item);
        }
        return true;
    }

Фрагмент

 @Override
    public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);  
            setHasOptionsMenu(true);      
        }

  @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
    {           
        super.onCreateOptionsMenu(menu, inflater);
    }

     @Override
        public boolean onOptionsItemSelected(MenuItem item)
        {
            switch (item.getItemId())
            {           
                case R.id.SomeIDInFragmentMenue:
                {             
                    break;
                }

                default:
                    return super.onOptionsItemSelected(item);
            }

            return true;
        }

Теперь строки (и подобные): "return super.onOptionsItemSelected(item);" в операции и фрагменте очень важны, потому что, как если бы вы выполнили код в отладке, вы увидите, что функции событий menue будут вызваны сначала в Activity, и если элемент не соответствует идентификатору в переключателе активности, case, строка дегазации: "super.onOptionsItemSelected(item);" будет вызывать функцию onOptionsItemSelected на фрагменте, как мы и хотели. (если у вас много фрагментов, убедитесь, что у них тоже есть эта строка, поскольку вызывающая гирархия может быть несколько сложной).

Ответ 5

Я использую actionbarsherlock. Это сработало для меня:

1) Создайте меню dummy_menu.xml

<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="match_parent" android:layout_width="fill_parent" >
<item
      android:title=""
      android:showAsAction="never"
      android:id="@+id/dummyMenu"
        />

2) В активности раздуйте меню следующим образом:

@Override
public boolean onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu) {
    com.actionbarsherlock.view.MenuInflater inflater = getSupportMenuInflater();
   inflater.inflate(R.menu.dummy_menu,menu);
   return super.onCreateOptionsMenu(menu);
}

3) В фрагментах onCreateView вызывает setHasOptionsMenu (true) и переопределяет onCreateOptionsMenu и onOptionsItemSelected также скрывает dummyMenu как это (в фрагменте)

    @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.fragment_actions, menu);
    MenuItem item = menu.findItem(R.id.dummyMenu);
    item.setVisible(false);
    super.onCreateOptionsMenu(menu, inflater);
}

Надеюсь, что это поможет кому-то.

Ответ 6

так просто, что вы можете сделать это в своем фрагменте, чтобы убедиться, что ваше действие будет правильно прослушиваться:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}

Ответ 7

У меня была эта проблема. Это было потому, что я преодолел неправильный метод

onOptionsItemSelected (элемент com.actionbarsherlock.view.MenuItem) это то, что я использовал.

Убедитесь, что вы используете правильный!

Ответ 8

Вы не привязываетесь к суперклассу в методах активности. У вас есть onCreateOptionsMenu() return super.onCreateOptionsMenu(menu) и имеет onOptionsItemSelected() return super.onOptionsItemSelected(item) (за исключением элемента, который вы обрабатываете, который должен возвращать true, чтобы указать, что вы обработали событие)