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>

Ответ 1

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

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

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

Ответ 2

В классе Activity

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

Ответ 3

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

Ответ 4

У меня была аналогичная проблема после создания специального макета для моей кнопки действий (я сделал кнопку "Изображение" и мне нужно было ее поместить и изменить некоторые другие вещи, поэтому мне пришлось использовать макет для нее). Затем 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..
       }
     });
 }

Ответ 5

Попробуйте использовать 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);
    }
}

Ответ 6

Если у вас есть динамически измененный пункт меню, например, меню значков (fooobar.com/info/48461/... или fooobar.com/info/48456/...), вы должны инициализировать элемент в 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);
}