Aquí está mi problema. Tengo una aplicación donde estoy usando ActionBar Sherlock con pestañas, fragmentos con menús de opciones. Cada vez que giro el emulador, se agregan menús para todos los fragmentos, incluso los que están ocultos/eliminados (probé ambos).onCreateOptionsMenu se está llamando demasiadas veces en ActionBar usando las pestañas
Este es el escenario: Una FragmentActivity, que tiene una Barra de acciones con
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);
Las pestañas todos utilizan el mismo Oyente:
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) {
}
}
Cada subclase de FragmentListBase tiene su propio menú y por lo tanto todos 3 subclases tienen:
setHasOptionsMenu(true);
y el apropiado
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
Log.d(TAG, "OnCreateOptionsMenu");
inflater.inflate(R.menu.il_options_menu, menu);
}
Cuando ejecuto la aplicación puedo ver que se llama al onCreateOptionsMenu varias veces, para todos los diferentes fragmentos.
Estoy totalmente perplejo.
Intenté publicar la mayor cantidad de código posible sin ser abrumador, si encuentra que falta algo, por favor avise.
[Editar] He añadido más registro, y resulta que el fragmento se adjunta dos (o más) veces en la rotación. Una cosa que noto es que todo se llama varias veces a excepción del método onCreate() que se llama una sola vez.
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
[Editar 2]
Ok, empecé a trazar de nuevo en código de Android y encontré esta parte aquí (que he editado para acortar este post).
/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);
}
}
}
El problema es que mAdded tiene de hecho varias instancias de FragmentList1 en ella, por lo que el método onCreateOptionsMenu() es " correctamente "siendo llamado 3 veces, pero para diferentes instancias de la clase FragmentList1. Lo que no entiendo es por qué esa clase se está agregando varias veces ... Pero eso es una gran ventaja.
Esta respuesta es demasiado complicada. Simplemente moviendo la llamada a 'bar.setNavigationMode (ActionBar.NAVIGATION_MODE_TABS)' antes de agregar pestañas a * ActionBar * solucionó mi problema. – Phil