Android: onOptionsItemSelected фрагмента не вызывается

У меня есть ActionBarActivity и один фрагмент. У действия нет раздутого меню, а у фрагмента есть меню с двумя кнопками. Фрагмент меню видно, но кнопки никак не реагируют на нажатия. При отладке я вижу, что вызываются как onCreateOptionsMenu() для Fragment, так и Activity, но при нажатии кнопок onOptionsItemSelected() не вызывается ни из Activity, ни из Fragment.

Активность

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    return false;
}

Фрагмент

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

    mainActivity = (NavigationActivity)getActivity();

    setHasOptionsMenu(true);
}

 @Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState){
    return (ScrollView) inflater.inflate(R.layout.tutoring_detail, container, false);
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.query_details_menu, menu);

    super.onCreateOptionsMenu(menu, inflater);

}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.accept_query:
            respondToQuery(true);
            return true;
        case R.id.decline_query:
            respondToQuery(false);
            return true;
        default:
            break;
    }

    return false;
}

Меню, отображаемое во фрагменте

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"

<item
    android:id="@+id/accept_query"
    android:orderInCategory="100"
    app:showAsAction="always"
    android:checkable="true"
    style="?android:attr/borderlessButtonStyle"
    app:actionViewClass="android.widget.ImageButton"/>

<item
    android:id="@+id/decline_query"
    android:orderInCategory="101"
    app:showAsAction="always"
    android:checkable="true"
    style="?android:attr/borderlessButtonStyle"
    app:actionViewClass="android.widget.ImageButton"/>
</menu>

person blavi    schedule 07.06.2015    source источник
comment
Вы намеренно используете устаревшую активность? Я могу привести вам пример с AppCompatActivity, который определенно работает и требует меньше времени для реализации.   -  person Evgeniy Mishustin    schedule 17.12.2015
comment
См. stackoverflow.com/a/39316878/3496570.   -  person AndroidGeek    schedule 02.05.2017


Ответы (7)


В классе «Активность»

 @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        super.onOptionsItemSelected(item);   
                return false;
}

Во Фрагменте,

@Override
    public void onCreate(@Nullable 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) {
    Toast.makeText(getActivity(), "called " + item.getItemId(), Toast.LENGTH_SHORT).show();
    return super.onOptionsItemSelected(item);
}
person Clevester    schedule 27.10.2016

Вы должны использовать super.onOptionsItemSelected(item) в методе onOptionsItemSelected(...) родительского действия.

Из Активность | Разработчики Android:

Производные классы должны обращаться к базовому классу, чтобы он выполнял обработку меню по умолчанию.

person d3dave    schedule 07.06.2015

Попробуйте переместить setHasOptionsMenu(true) внутри метода onCreateView() в вашем фрагменте вместо onCreate().

person Bidhan    schedule 07.06.2015
comment
Спасибо, но onOptionsItemSelected() по-прежнему не вызывается. Я пробовал оба предложенных решения, по отдельности и вместе, но без изменений. - person blavi; 07.06.2015

У меня была аналогичная проблема после создания специального макета для моей кнопки действия (я сделал кнопку изображения, и мне нужно было дополнить ее и изменить некоторые другие вещи, поэтому мне пришлось использовать для нее макет). Затем onOptionsItemSelected потерял связь с этим imageButton, поэтому я просто использую для него clickListener внутри onCreateOptionsMenu. Возможно, это не лучшая практика, возможно, есть лучшее решение, но это то, что решает мою проблему.

public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    inflater.inflate(R.menu.picker_list_menu, menu);

    MenuItem itemDone = menu.findItem(R.id.menu_done);
    MenuItemCompat.setActionView(itemDone, R.layout.menu_layout_done);
    menuDoneIB = (ImageButton) MenuItemCompat.getActionView(itemDone);
    itemDone.getActionView().setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View v) {
            //your code..
       }
     });
 }
person Udi Reshef    schedule 17.12.2015
comment
Спасибо. У меня также есть специальная кнопка меню с изменением текста значка. А также не может вызвать меню, щелкнув по нему. В моем случае у меня есть панель инструментов внутри активности, и я меняю текст значка в onPrepareOptionsMenu. Однако, если я изменю в menu_fragment.xml app:showAsAction="withText" или "never", так что элемент будет скрыт над 3 вертикальными точками, он станет интерактивным (потому что мы можем щелкнуть заголовок элемента). До сих пор нет прогресса, и если исправлю, то напишу. - person CoolMind; 26.08.2016
comment
Хотя я мог бы сделать это с помощью onPrepareOptionsMenu, лучший способ написан рядом: stackoverflow.com/a/39174874/2914140. - person CoolMind; 27.08.2016

Попробуйте использовать oncreateview

public static class ExampleFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.example_fragment, container, false);
    }
}
person Community    schedule 07.06.2015
comment
У меня уже был onCreateView для установки представления. Я редактировал с помощью onCreateView - person blavi; 08.06.2015

Если у вас есть динамически измененный пункт меню, например, меню значка (https://stackoverflow.com/a/16648170/2914140 или https://stackoverflow.com/a/26017587/2914140), вы должны инициализировать элемент в onCreateOptionsMenu и переустанавливать setOnClickListeners после каждого изменения элемента. В моем случае:

private MenuItem menuItem;

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.menu_catalog, menu);

    menuItem = menu.findItem(R.id.action_badge);
    writeBadge(0);

    super.onCreateOptionsMenu(menu, inflater);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == R.id.action_badge) {
        // Your code.
        return true;
    }
    return super.onOptionsItemSelected(item);
}

private void writeBadge(int count) {
    MenuItemCompat.setActionView(menuItem, R.layout.item_badge);
    RelativeLayout layout = (RelativeLayout) MenuItemCompat.getActionView(menuItem);
    // A TextView with number.
    TextView tv = (TextView) layout.findViewById(R.id.badge);
    if (count == 0) {
        tv.setVisibility(View.INVISIBLE);
    } else {
        tv.setVisibility(View.VISIBLE);
        tv.setText(String.valueOf(count));
    }
    // An icon, it also must be clicked.
    ImageView imageView = (ImageView) layout.findViewById(R.id.image);
    View.OnClickListener onClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            onOptionsItemSelected(menuItem);
        }
    };
    menuItem.getActionView().setOnClickListener(onClickListener);
    imageView.setOnClickListener(onClickListener);
}
person CoolMind    schedule 26.08.2016

Я передаю событие щелчка фрагменту из действия. Это сработало для меня.

@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
    return getSupportFragmentManager().getFragments().get(getSupportFragmentManager().getFragments().size() - 1)
            .onOptionsItemSelected(item);
}
person zohaib khaliq    schedule 12.02.2020