FragmentStatePageAdapter дублирует пункты меню ActionBar

У меня проблема с FragmentStatePageAdapter (который я использую в качестве адаптера для ViewPager) и элементы меню из панели действий.

Когда я запускаю приложение, все в порядке. Если я переведу задачу в фоновый режим (например, нажав кнопку ДОМОЙ), и я начну делать вещи до завершения действия, а затем, когда я вернусь к моему приложению (через панель запуска или уведомление, которое я создаю), все в порядке, за исключением того, что есть Дублированные пункты меню в панели действий.

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

Если я заменилFragmentStatePageAdapter на FragmentPageAdapter, элементы больше не дублируются, но фрагменты не отображаются в функции ViewPager (getItem () из адаптера никогда не вызывается, поэтому он не возвращает какой-либо фрагмент).

Есть идеи? Способ избежать FragmentStatePageAdapter для дублирования пунктов меню? Возможно, используйте FragmentPageAdapter, но с модификацией, чтобы показать фрагменты? Модификация моих фрагментов?

Вот некоторые фрагменты кода из моего приложения …

Как элементы меню создаются внутри фрагментов:

@Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { /* Create play button */ final MenuItem mPlay = menu.add(R.string.play_all); mPlay.setIcon(R.drawable.ic_play_all); mPlay.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); mPlay.setOnMenuItemClickListener(new OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { final List<Song> songs = getSongs(); if (songs.size() == 0) { /* Show message */ Toast.makeText(mContext, R.string.no_song_list, Toast.LENGTH_LONG).show(); } else { /* Play song list */ try { PlayManager.getService().playList(songs); } catch (Exception e) {} } return false; } }); /* Create menu */ super.onCreateOptionsMenu(menu, inflater); } 

Как фрагменты создаются в адаптере ViewPager

 @Override public Fragment getItem(int position) { final Class<?> cls = mTabs.get(position); /* No tab */ if (cls == null) return null; /* Instantiate fragment */ final Fragment fragment = Fragment.instantiate(mContext, cls.getName(), null); /* Add to list */ mFragments.put(position, fragment); /* Return fragment */ return fragment; } 

Благодаря!

PS: Я попытался изменить startMode операции на «singleTop», и я также попытался вернуть в getItem () ранее созданный фрагмент (но это бесполезно, поскольку getItem () никогда не вызывается, когда я возвращаюсь к приложению, как я сказал до).

Solutions Collecting From Web of "FragmentStatePageAdapter дублирует пункты меню ActionBar"

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

Следующий код исправил мою проблему:

 @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.remove("android:support:fragments"); } 

Так же просто, как написать этот фрагмент кода в той операции, где я создаю экземпляр и использовать фрагменты.

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

Перед тем, как раздувать меню опций в вашем фрагменте внутри ViewPager, проверьте, видимо ли экземпляр фрагмента, чтобы предотвратить дублирование пунктов меню:

 // This should be in your Fragment implementation public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { if(isVisible()) { inflater.inflate(R.menu.menu_fragment, menu); } super.onCreateOptionsMenu(menu, inflater); } 

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

Есть, я думаю, два решения:

  1. Возьмите манипуляции с панелью действий из фрагментов. Вместо того, чтобы устанавливать onclick для элемента меню внутри фрагмента, вы отправляете сообщение в текущий фрагмент из Activity.

  2. Используйте Menu.findItem (), чтобы увидеть, добавил ли еще один фрагмент желаемого элемента MenuItem, и если приложите к нему текущий фрагмент (в onPrepareOptionsMenu ()).

Я нашел какое-то решение, это может быть работа

В дубликатном фрагменте меню добавьте menu.clear() перед тем, как файл меню надуть в onCreateOptionsMenu(Menu menu, MenuInflater inflater)

 @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); menu.clear(); inflater.inflate(R.menu.main,menu); }