Вот моя проблема. У меня есть приложение, в котором я использую ActionBar Sherlock с вкладками, фрагменты с опциями меню. Каждый раз, когда я поворачиваю эмулятор, добавляются меню для всех фрагментов, даже тех, которые скрыты / удалены (я пробовал оба).
Это настройка: One FragmentActivity, которая имеет панель действий с
final ActionBar bar = getSupportActionBar();
bar.addTab(bar.newTab()
.setText("1")
.setTabListener(new MyTabListener(new FragmentList1())));
bar.addTab(bar.newTab()
.setText("2")
.setTabListener(new MyTabListener(new FragmentList2())));
bar.addTab(bar.newTab()
.setText("3")
.setTabListener(new MyTabListener(new FragmentList3())));
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayShowHomeEnabled(true);
bar.setDisplayShowTitleEnabled(true);
Все вкладки используют один и тот же прослушиватель:
private class MyTabListener implements ActionBar.TabListener {
private final FragmentListBase m_fragment;
public MyTabListener(FragmentListBase fragment) {
m_fragment = fragment;
}
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
FragmentManager fragmentMgr = ActivityList.this.getSupportFragmentManager();
FragmentTransaction transaction = fragmentMgr.beginTransaction();
transaction.add(R.id.frmlyt_list, m_fragment, m_fragment.LIST_TAG);
transaction.commit();
}
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
FragmentManager fragmentMgr = ActivityList.this.getSupportFragmentManager();
FragmentTransaction transaction = fragmentMgr.beginTransaction();
transaction.remove(m_fragment);
transaction.commit();
}
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
}
Каждый подкласс FragmentListBase имеет свое собственное меню, и поэтому все 3 подкласса имеют:
setHasOptionsMenu(true);
и соответствующий
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
Log.d(TAG, "OnCreateOptionsMenu");
inflater.inflate(R.menu.il_options_menu, menu);
}
Когда я запускаю приложение, я вижу, что onCreateOptionsMenu вызывается несколько раз для всех разных фрагментов.
Я в полном замешательстве.
Я попытался опубликовать как можно больше кода без лишних хлопот, если вы обнаружите, что чего-то не хватает, пожалуйста, сообщите.
[Изменить]
Я добавил больше логов, и оказалось, что фрагмент прикрепляется дважды (или больше) при ротации. Я заметил одну вещь: все вызывается несколько раз, кроме метода onCreate (), который вызывается только один раз.
06.704:/WindowManager(72): Setting rotation to 0, animFlags=0
06.926:/ActivityManager(72): Config changed: { scale=1.0 imsi=310/260 loc=en_US touch=3 keys=1/1/2 nav=1/2 orien=L layout=0x10000014 uiMode=0x11 seq=35}
07.374:/FragmentList1(6880): onAttach
07.524:/FragmentList1(6880): onCreateView
07.564:/FragmentList1(6880): onAttach
07.564:/FragmentListBase(6880): onCreate
07.564:/FragmentList1(6880): OnCreateOptionsMenu
07.574:/FragmentList1(6880): OnCreateOptionsMenu
07.604:/FragmentList1(6880): onCreateView
[Изменить 2]
Хорошо, я начал прослеживать код Android и нашел эту часть здесь (которую я отредактировал, чтобы сократить этот пост).
/ com_actionbarsherlock / SRC / Android / поддержка / v4 / приложение / FragmentManager.java
public boolean dispatchCreateOptionsMenu(Menu menu, MenuInflater inflater) {
if (mActive != null) {
for (int i=0; i<mAdded.size(); i++) {
Fragment f = mAdded.get(i);
if (f != null && !f.mHidden && f.mHasMenu) {
f.onCreateOptionsMenu(menu, inflater);
}
}
}
Проблема в том, что в mAdded действительно есть несколько экземпляров FragmentList1, поэтому метод onCreateOptionsMenu () «правильно» вызывается 3 раза, но для разных экземпляров класса FragmentList1. Чего я не понимаю, так это того, почему этот класс добавляется несколько раз ... Но это чертовски хороший пример.