これが私の問題です。タブ付きのActionBar Sherlock、オプションメニュー付きのフラグメントを使用しているアプリがあります。エミュレーターを回転させるたびに、非表示/削除されたものも含め、すべてのフラグメントにメニューが追加されます (両方を試しました)。
設定は次のとおりです。
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 が複数回呼び出されていることがわかります。
私は完全に困惑しています。
圧倒されることなく、できるだけ多くのコードを投稿しようとしましたが、何か不足している場合はお知らせください。
[編集] ログを追加したところ、ローテーションでフラグメントが 2 回 (またはそれ以上) 接続されていることがわかりました。私が気づいたことの 1 つは、1 回だけ呼び出される 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/support/v4/app/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 クラスの異なるインスタンスに対してです。私が理解できないのは、なぜそのクラスが複数回追加されているのかということです...しかし、それは良い手がかりです。