Android: невозможно скрыть пункт меню в ActionBar дочернего фрагмента

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

Мой options_menu.xml выглядит следующим образом

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_search"
      android:title="@string/search_title"
      android:icon="@drawable/ic_action_search"
      android:showAsAction="collapseActionView|ifRoom"
      android:actionViewClass="android.widget.SearchView" />
<item
    android:id="@+id/menu_share"
    android:icon="@android:drawable/ic_menu_share"
    android:showAsAction="always"
    android:title="Share"/>
</menu>

Я показываю это меню в ParentFragment, где я скрываю menu_shareиспользуя этот код

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

     inflater.inflate(R.menu.options_menu, menu);
    menu.findItem(R.id.menu_share).setVisible(false);
}

Это успешно скрывает параметр Share. Теперь этот фрагмент открывает новый фрагмент, то есть дочерний фрагмент.

В этом дочернем фрагменте я хочу скрыть элемент Search и показать только параметр Share. Но использование того же кода здесь не поможет.

   @Override
public void  onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.options_menu, menu);
    menu.findItem(R.id.menu_search).setVisible(false);

}

Я даже пытался поставить getActivity().invalidateOptionsMenu();, но безрезультатно, на панели действий всегда отображаются оба пункта меню. Пожалуйста, помогите мне понять, что вызывает это.

ЖУРНАЛ ОШИБОК

E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: info.androidhive.slidingmenu, PID: 27321
java.lang.NullPointerException
        at info.androidhive.slidingmenu.HomeFragment.onPrepareOptionsMenu(HomeFragment.java:476)
        at android.app.Fragment.performPrepareOptionsMenu(Fragment.java:1794)
        at android.app.FragmentManagerImpl.dispatchPrepareOptionsMenu(FragmentManager.java:1964)
        at android.app.Activity.onPreparePanel(Activity.java:2665)
        at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java:540)
        at com.android.internal.policy.impl.PhoneWindow.doInvalidatePanelMenu(PhoneWindow.java:881)
        at com.android.internal.policy.impl.PhoneWindow$1.run(PhoneWindow.java:297)
        at android.os.Handler.handleCallback(Handler.java:733)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:146)
        at android.app.ActivityThread.main(ActivityThread.java:5593)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
        at dalvik.system.NativeStart.main(Native Method)

person Swapna Lekshmanan    schedule 28.04.2015    source источник
comment
если у вас нет необходимости, вы можете удалить все исходники из кода из пунктов меню, еще много решений здесь   -  person Amitsharma    schedule 28.04.2015
comment
Посмотрите здесь developer.android.com/guide/topics/ui/menus.html или этот androidhive.info/2011/09 /how-to-create-android-меню   -  person Amitsharma    schedule 28.04.2015


Ответы (3)


Вместо того, чтобы скрывать меню в методе onCreateOptionsMenu, вы можете попробовать скрыть его в onPrepareOptionsMenu в своей родительской активности, частью которой являются ваши фрагменты/дочерние фрагменты. Просто проверьте, виден ли этот фрагмент (это можно сделать, назначив имя тега каждому фрагменту), а затем напишите свой код, чтобы скрыть меню, если вы находитесь в этом фрагменте. Я надеюсь, что это поможет вам.

вы можете сделать что-то подобное в методе onPrepareOptionsMenu:

Fragment frag = getSupportFragmentManager().findFragmentByTag("ВАШФРАГМЕНТ");

    if (frag != null && frag.isVisible()) {
      menu.findItem(R.id.menu_search).setVisible(false);
    } else {
        menu.findItem(R.id.menu_share).setVisible(false);
    }
        return super.onPrepareOptionsMenu(menu);
person Ravi Kabra    schedule 28.04.2015
comment
теперь мой дочерний фрагмент показывает 3 элемента › Share Search Share.. :(. новый общий ресурс добавлен в список - person Swapna Lekshmanan; 28.04.2015
comment
Hie swapna, вы пытались очистить меню, а затем посмотрели на настройку видимости для обоих пунктов меню? - person Ravi Kabra; 28.04.2015
comment
Вы также можете изменить условия видимости фрагмента (если и еще часть) с вашими дочерними фрагментами. Проверьте, какой является вашим родительским фрагментом, а затем внутри него, если вы также вызываете дочерний фрагмент. Измените это условие соответствующим образом. Это будет работать. - person Ravi Kabra; 28.04.2015
comment
if (frag != null && frag.isVisible()) { menu.clear(); getMenuInflater().inflate(R.menu.options_menu, меню); Элемент MenuItem = menu.findItem(R.id.menu_search); item.setTitle(Поиск); } еще { menu.clear(); getMenuInflater().inflate(R.menu.options_menu, меню); Элемент MenuItem = menu.findItem(R.id.menu_share); item.setTitle(Поделиться); } Вы пробовали так? - person Ravi Kabra; 28.04.2015
comment
всякий раз, когда я ставлю menu.clear, приложение просто вылетает при запуске.. все еще пробую разные способы.. я думал о создании разных меню для каждого фрагмента. но затем элементы начинают перекрываться.. что-то здесь серьезно не так - person Swapna Lekshmanan; 28.04.2015
comment
Пожалуйста, прикрепите соответствующий журнал ошибок здесь. Я думаю, что вы что-то упустили перед очисткой меню, которое требуется. Отныне я думаю, что по этой причине ваше приложение разбивается, как вы сказали, вы получаете исключение NullPointerException. - person Ravi Kabra; 28.04.2015
comment
Давайте продолжим обсуждение в чате. - person Swapna Lekshmanan; 28.04.2015

как в основном фрагменте, так и в подфрагменте, скройте меню onStop() и покажите меню onResume().

person Thinsky    schedule 28.04.2015

Попробуйте вызвать суперметод Fragment, чтобы использовать родительский элемент menu Активность.

В методе onCreate фрагмента вызовите setHasOptionsMenu(true);

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

Переопределите onCreateOptionsMenu в своем фрагменте и используйте класс MenuItem для управления элементами в вашем android-actionbar как хотите, см. код ниже.

public class NewsViewFragment extends Fragment {

    public NewsViewFragment() {
    }

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

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

        MenuItem item = menu.findItem(R.id.action_news_search);

        if (SOME_BOOLEAN_VALUE) {
            item.setVisible(false);
        } else {
            item.setVisible(true);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_news_view, container, false);
    }

}

Надеюсь, это поможет вам.

person Martín Serrano    schedule 20.04.2016