Как скрыть OptionsMenu на NavigationDrawer с помощью фрагментов?

Я создаю приложение для Android, и я стараюсь уважать как можно больше новейших стандартов юзабилити Android. В частности, я готовлю пользовательский интерфейс с помощью навигационного ящика, и я пытаюсь обеспечить совместимость с версиями Android версии 2.1+. Чтобы оценить проблему, проект состоит из:

  • Основная деятельность;
  • Ящик для навигации;
  • Четыре фрагмента (с их соответствующими макетами).

Проблема, с которой я столкнулся, возникает при открытии ящика навигации: хотя у каждого Fragment есть свое конкретное меню, когда я открываю навигационный ящик, он добавляется в меню навигационного ящика. Я попытался несколькими способами ( invalidateOptionMenu() , menu.clear() , манипулируя функциями isDrawerOpen() и isDrawerClose() и т. Д.), Но я не могу удалить меню Fragment при открытии навигатора.

Это некоторые фрагменты моего кода, большая часть которых сгенерирована Android Studio, IDE, которую я использую:

В основной деятельности:

 @Override public boolean onCreateOptionsMenu(Menu menu) { if (!mNavigationDrawerFragment.isDrawerOpen()) { // Only show items in the action bar relevant to this screen // if the drawer is not showing. Otherwise, let the drawer // decide what to show in the action bar. getMenuInflater().inflate(R.menu.global, menu); restoreActionBar(); return true; } return super.onCreateOptionsMenu(menu); } 

Где «global» – это простое меню с классическим «ic_action_overflow».

И в моих фрагментах я:

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); } @Override public void onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); inflater.inflate(R.menu.fragment1, menu); } 

(То же самое относится к другому Fragment s).

Кто-то может дать мне несколько советов о том, как действовать?

Я столкнулся с той же проблемой, используя код шаблона, созданный Android Studio, и получил его работу, изменив меню в NavigationDrawerFragment.onPrepareOptionsMenu() (в моем случае я хотел полностью очистить меню):

 @Override public void onPrepareOptionsMenu(Menu menu) { if (mDrawerLayout != null && isDrawerOpen()) { menu.clear(); } } 

Это примерно то, как воссоздано меню опций:

  1. NavigationDrawerFragment , созданный IDE, вызывает supportInvalidateOptionsMenu() когда ящик открыт или закрыт.
  2. onCreateOptionsMenu получает вызов : активность хостинга и каждый добавленный фрагмент получает возможность вносить элементы меню.
  3. onPrepareOptionsMenu получает вызов : снова активность хостинга и каждый из добавленных фрагментов получают возможность изменить меню.

Эти фрагменты повторяются в том порядке, в котором они были добавлены . Невозможно остановить цепочку вызовов на полпути в шагах 2 и 3.

Поэтому идея состоит в том, чтобы позволить NavigationDrawerFragment делать последние изменения в меню в onPrepareOptionsMenu и никакие другие фрагменты.

Если вам нужно позволить другим фрагментам что-то делать в onPrepareOptionsMenu , тогда вам, возможно, придется настроить эти другие фрагменты, чтобы они могли определить, открыт ли ящик или нет, и соответственно изменить их поведение. Это может означать, возможно, добавление метода isDrawerOpen к активности хостинга или передачу идентификаторов ящика фрагменту, как это сделано в NavigationDrawerFragment.setup() .

В своем фрагменте onCreate добавьте следующее:

 setHasOptionsMenu (true); 

И затем спрячьтесь черезPrepareOptionsMenu. например

 @Override public void onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); menu.findItem(R.id.action_settings).setVisible(false); } 

Если вы внедрили навигационный ящик так, как Android Studio настроит его для вашего кода в коде с помощью NavigationDrawerFragment , у вас должно быть два xml для начала с main.xml (элементы меню действий в масштабе действия) и global.xml (глобальные элементы ). Затем я добавил меню, специфичное для фрагментов, которое добавляет элементы в «пункты меню действий», пока ящик закрыт …

Мероприятия:

 @Override public boolean onCreateOptionsMenu(Menu menu) { if (!mNavigationDrawerFragment.isDrawerOpen()) { // Only show items in the action bar relevant to this activity // if the drawer is not showing. Otherwise, let the drawer // decide what to show in the action bar. getMenuInflater().inflate(R.menu.main, menu); this.menu = menu; restoreActionBar(); return true; } return super.onCreateOptionsMenu(menu); } 

NavigationDrawerFragment

 @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { // If the drawer is open, show the global app actions in the action bar. // See also showGlobalContextActionBar, which controls the top-left area // of the action bar. if (mDrawerLayout != null && isDrawerOpen()) { inflater.inflate(R.menu.global, menu); showGlobalContextActionBar(); } super.onCreateOptionsMenu(menu, inflater); } 

И в ваших фрагментах добавить, как вы описали выше

 @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { // Add fragment specific action bar items to activity action bar items. // Activity wide items are in main.xml // Visible action bar items if navigation drawer is visible/open // are in global.xml super.onCreateOptionsMenu(menu, inflater); if (!mNavigationDrawerFragment.isDrawerOpen()) { inflater.inflate(R.menu.fragment_menu, menu); } } 

Ознакомьтесь с этим ответом здесь: https://stackoverflow.com/a/18135409/2558344 . Его в основном используют логические для очистки элементов в навигационном ящике и наоборот. Но в качестве альтернативы вы можете объявить Menu menu в качестве частной переменной в своем классе и использовать его как: onCreateOptionsMenu(menu, MenuInflater inflater) .

Затем проверьте свои фрагменты onStop() , onPause() если они отображают элементы или нет, если да, то очистите их, например:

 if (menu != null) menu.clear();