OnCreateOptionsMenu(), вызываемый дважды в фрагменте
У меня есть простое приложение с меню опций, которое меняется в начале фрагментов.
Проблема в том, что в начале все фрагменты, кроме первого onCreateOptionsMenu(), вызываются дважды - внутри onCreate() и after onResume().
В onCreate() я называю это вручную через setHasOptionsMenu (true), но после onResume() этого не должно произойти.
Кроме того, это происходит только после начала первого фрагмента.
Вот код базовых фрагментов:
class BaseFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle clicks
return true;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Create a menu
super.onCreateOptionsMenu(menu, inflater);
}
}
И изменение кода фрагментов в Activity:
public void startFragment(BaseFragment fragment) {
getSupportFragmentManager()
.beginTransaction()
.replace(android.R.id.content, fragment)
.commit();
}
Образец не использует внешнюю библиотеку, такую как ActionBarSherlock, только SupportLibrary.
Я полагаю, проблема заключается в методе FragmentTransaction replace(), потому что он отлично работает, когда начинается первый фрагмент. Но я не знаю, с чего начать решать проблему. Мне нужно точно заменить фрагмент в представлении.
Ответы
Ответ 1
Я знаю, что опаздываю на вечеринку, но столкнулся с той же проблемой, и моим решением было явно добавить
setHasOptionsMenu(false);
к моей функции SupportFragments onCreate. Это предотвращает любые дополнительные вызовы для действий onCreateOptionsMenu и onPrepareOptionsMenu. Надеюсь, это поможет.
Ответ 2
Я предполагаю, что вновь добавленный фрагмент снова вызывает действия onCreateOptionsMenu!
1 > Попробуйте добавить
setRetainInstance (истина);
для создания фрагмента!
public BaseFragment()
{
setRetainInstance(true);
setHasOptionsMenu(true);
}
Это спасет/восстановит отдельные состояния каждого из фрагментов при вращении
Проблема, по-видимому, связана с тем, что Android не уничтожает фрагмент, когда действие уничтожается (когда устройство повернуто).
Я нашел это здесь Джейк Уортон в SO
Обновление:
2 > Другой способ - не добавлять фрагменты в файл макета, а также создавать их вручную, вызывая метод constructor/newInstance.
Если вы добавите фрагмент в макет, инфраструктура android создаст его для вас.
Вместо того, чтобы вручную создавать фрагменты, вы должны получить его экземпляр, вызвав FragmentManager.getFragmentById и вместо этого используйте этот экземпляр.
Поэтому всегда указывайте идентификатор и/или тег для ваших фрагментов
3 > Попробуйте это, вызвав menu.clear()
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
inflater.inflate(R.menu.call_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
Ответ 3
Самый простой способ решить проблему - очистить меню перед его завышением.
menu.clear() очистит любое существующее меню и начнет со следующего.
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.sample_menu, menu);
}
Ответ 4
Возможно, вы можете попробовать это следующим образом:
private final int MENU_SEARCH=Menu.FIRST;
:
@Override public void onPrepareOptionsMenu(Menu menu) {
if (menu.findItem(MENU_SEARCH)==null) {
menu.add(0, MENU_SEARCH, Menu.NONE, getText(R.string.menu_search));
:
т.е. проверьте, существует ли в меню один из ваших пунктов меню, а если нет, возможно, все они должны быть добавлены.
Ответ 5
Если вы не обрабатываете элемент меню, вы должны вызвать реализацию суперкласса onOptionsItemSelected() (реализация по умолчанию возвращает false).
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}