这是我的问题。我有一个应用程序,其中我使用ActionBar Sherlock与选项卡、片段和选项菜单。每次我旋转模拟器���,即使隐藏或删除了某些选项卡,所有片段的菜单都会被添加(我尝试了两种方法)。
这是设置:一个FragmentActivity,它具有带选项菜单的ActionBar。
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的每个子类都有自己的菜单,因此所有三个子类都具有:
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/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()方法会正确地针对不同的FragmentList1类实例被调用3次。我不明白的是为什么该类会被多次添加... 但这是一个非常好的线索。
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS)
即可解决我的问题。 - Phil