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


EDIT: Этот вопрос был для устаревшей панели действий Шерлока. Вместо этого теперь должна использоваться библиотека поддержки Android

я добавил опцию меню панели действий под названием share for my 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().

8 80

8 ответов:

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

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

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

наконец решить эту проблему, перейдя по ссылке http://developer.android.com/guide/topics/ui/actionbar.html

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

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

код следующим образом ----- Удалите обработчик для R. действие.добавить on 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. действие.добавить на фрагменте выглядит так:

@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 в Фрагмент

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

  1. добавить setHasOptionsMenu(true) метод в вашем фрагменте onCreate(Bundle savedInstanceState) метод.

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

  3. внутри метод, убедитесь, что вы вернуть false когда действие пункта меню будет реализован в фрагменте 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's 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;
}

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

активность

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

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

Я использую 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);
}

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

редактировать для actionbar Шерлок использовать

Я должен использовать

public boolean onMenuItemSelected(int featureId, MenuItem item) {

в основной деятельности, чтобы захватить пункт меню

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

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

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

onOptionsItemSelected(com.actionbarsherlock.вид.Элемент меню) то, что я использовал.

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

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