OnOptionsItemSelected фрагмента не вызывается

Мой фрагмент заменяет родительские параметры действий определенным элементом, но когда я нажимаю на элемент, только действия onOptionItemSelected вызывается eventhough я переопределил метод внутри Fragment. Я что-то пропустил?

Методы фрагмента:

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

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {

    Log.d(TAG, "Fragment.onCreateOptionsMenu");

    if (mPasteMode) {
        menu.clear();
        inflater.inflate(R.menu.contexual_paste, menu);
        getActivity().getActionBar().setTitle("PasteMode");
    }
    super.onCreateOptionsMenu(menu, inflater);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    Log.d(TAG, "Fragment.onOptionsItemSelected");

    switch (item.getItemId()) {
        case R.id.context_action_paste:
            Toast.makeText(getActivity(),
                     "It worked ",
                    Toast.LENGTH_SHORT).show();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

Методы деятельности:

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    Log.d(TAG, "MainActivitiy.onOptionsItemSelected");
    switch (item.getItemId()) {
        case R.id.action_refresh:
            Toast.makeText(this, "Action Refresh selected", Toast.LENGTH_SHORT).show();
            break;
        default:
            break;
    }
    return true;
}

Выход Logcat:

MainActivity.onCreateOptionsMenu
Fragment.onCreateOptionsMenu
MainActivitiy.onOptionsItemSelected

Так как я могу иметь onOptionsItemSelected фрагмента называется?

7 ответов

Решение

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

Если метод onOptionsItemSelected вашего Activity возвращается в true, вызов используется в активности, а onOptionsItemSelected фрагмента не вызывается. Итак, верните false в вашем методе Activity onOptionsItemSelected или реализации родительского класса через вызов super.onOptionsItemSelected (реализация по умолчанию возвращает false).

В соответствии с классом Activity javadoc, метод Activity.onOptionsItemSelected должен:

Возвратите false, чтобы позволить нормальной обработке меню продолжаться, true, чтобы потреблять это здесь

В моем случае я не добавлял никаких пунктов меню (т.е. я не звонил onCreateOptionsMenu либо в упражнении, либо во фрагменте). Однако мне нужно было использовать кнопку "Домой" (вверх) на панели действий во фрагменте. Для этого я должен был убедиться, что setHasOptionsMenu(true) был вызван во фрагменте onCreateView() Метод, прежде чем это могло бы работать. Тогда мне не нужно onOptionsItemSelected переопределить в моей деятельности.

После нескольких часов работы над этой проблемой я нашел решение.

Вам нужно вызвать onOptionsItemSelected в действии, но вернуть false, как это

Вот и все.

Я нашел решение, т.е.

Fragment.class

 @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    // Do something that differs the Activity's menu here
    //MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.wifinity_setting, menu);
    for (int i = 0; i < menu.size(); i++) {
        MenuItem item = menu.getItem(i);
        SpannableString spanString = new SpannableString(menu.getItem(i).getTitle().toString());
        spanString.setSpan(new ForegroundColorSpan(Color.BLACK), 0, spanString.length(), 0); //fix the color to white
        item.setTitle(spanString);
    }
    super.onCreateOptionsMenu(menu, inflater);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {

        case R.id.menu1:
            Intent intent3 = new Intent(context, activity.class);
            startActivity(intent3);
            return true;

    }
    return true;
}

ACtivity.class

переопределить onOptionsItemSelected() // вызывается метод fragmnets onOptionselected.. это решение работает для меня

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {

        default:
            if(fragment != null)
                fragment.onOptionsItemSelected(item);
    }
    return true;
}

Я согласен с принятым в настоящее время решением, но другая возможная причина - неоднозначная ссылка на класс. У меня был собственный класс в моем проекте с именем MenuItem, и мой фрагмент интерпретировал этот custom.MenuItem как тип параметра вместо android.view.MenuItem

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

      if you are using view binding in your fragment you can populate menu using below code 

in your onCreate method use 

step 1 setHasOptionsMenu(true)
step 2 inflate menu by like below binding.actionBar.toolbar.inflateMenu(R.menu.home_screen_menu)

step 3 binding.actionBar.toolbar.setOnMenuItemClickListener {
            onOptionsItemSelected(it)
        }

then override 
override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
           case 1{}
           case 2{}
    }
Другие вопросы по тегам