2011-12-27 12 views
19

Estoy agregando pestañas de navegación a una barra de acción utilizando el código de ejemplo proporcionado aquí: http://developer.android.com/guide/topics/ui/actionbar.html Estoy usando ActionBarSherlock.Fragmento nulo Transición de Transaction a TabListener.onTabSelected()

Mi TabListener se copia directamente de los documentos.

public static class TabListener<T extends Fragment> implements ActionBar.TabListener { 
    private Fragment mFragment; 
    private final Activity mActivity; 
    private final String mTag; 
    private final Class<T> mClass; 

    /** Constructor used each time a new tab is created. 
     * @param activity The host Activity, used to instantiate the fragment 
     * @param tag The identifier tag for the fragment 
     * @param clz The fragment's Class, used to instantiate the fragment 
     */ 
    public TabListener(Activity activity, String tag, Class<T> clz) { 
     mActivity = activity; 
     mTag = tag; 
     mClass = clz; 
    } 

    /* The following are each of the ActionBar.TabListener callbacks */ 

    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) { 
     // Check if the fragment is already initialized 
     if (mFragment == null) { 
      // If not, instantiate and add it to the activity 
      mFragment = Fragment.instantiate(mActivity, mClass.getName()); 
      ft.add(android.R.id.content, mFragment, mTag); 
     } else { 
      // If it exists, simply attach it in order to show it 
      ft.attach(mFragment); 
     } 
    } 

    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) { 
     if (mFragment != null) { 
      // Detach the fragment, because another one is being attached 
      ft.detach(mFragment); 
     } 
    } 

    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) { 
     // User selected the already selected tab. Usually do nothing. 
    } 
} 

Y puedo configurar al oyente en mi actividad:

ActionBar.Tab tab = actionBar.newTab(); 
    tab.setText(getString(R.string.TAB_CALC)); 
    tab.setTabListener(new TabListener<StrokeSelectorFragment>(this, "blah", StrokeSelectorFragment.class)); 
    actionBar.addTab(tab); 

embargo, la aplicación hace saltar con una excepción de puntero nulo porque un FragmentTransaction nulo se pasa a onTabSelected() en el oyente. ¿Debo crear uno en alguna parte?

He estado leyendo una y otra vez los documentos, y estoy bastante confundido. ¿Puedes ver lo que me he perdido?

+0

El código de ejemplo de actividad en este informe de error ActionBarSherlock ayudará: https://github.com/JakeWharton/ActionBarSherlock/pull/402 –

Respuesta

15

Esto parece ser un problema con la biblioteca de compatibilidad (y, por lo tanto, por la asociación ActionBarSherlock). La solución es ignorar el FragmentTransaction (nulo) que se transfiere y obtener uno propio. He aquí un ejemplo de la marca Murphy:

 FragmentManager fragMgr = getSupportFragmentManager(); 
     FragmentTransaction ft = fragMgr.beginTransaction(); 
     ft.commit(); 

https://groups.google.com/forum/#!msg/android-developers/pCnSx7sTIZ8/cTt1L91M2NgJ

https://groups.google.com/group/actionbarsherlock/browse_thread/thread/89eac58c13fe1ae0

+0

commit() es necesario en este caso? El doctor dice "no" pero lo pones, ¿por qué? Y en mis pruebas, solo funciona con commit(). –

16

me encontré con el post de arriba Ollie útiles, pero no lo suficientemente detallada. Me logrado refactorizar el código proporcionado en el ActionBar Guide de la siguiente manera (nota: usted tiene que hacer el mismo cambio en los otros métodos implementados en el TabListener):

public void onTabSelected(Tab tab, FragmentTransaction ignoredFt) { 
    FragmentManager fragMgr = ((FragmentActivity)mActivity).getSupportFragmentManager(); 
    FragmentTransaction ft = fragMgr.beginTransaction(); 

    // Check if the fragment is already initialized 
    if (mFragment == null) { 
     // If not, instantiate and add it to the activity 
     mFragment = Fragment.instantiate(mActivity, mClass.getName()); 

     ft.add(android.R.id.content, mFragment, mTag); 
    } else { 
     // If it exists, simply attach it in order to show it 
     ft.attach(mFragment); 
    } 
} 
+3

Gracias por esto. Curiosamente, al principio me olvidé de agregar la llamada ft.commit sin consecuencias obvias. –

+0

Cheers @Boswell, también lo eché de menos y solo lo vi gracias a tu comentario – Dan2552

+0

Mejor que la respuesta anterior. –

1

Fue error en ActionBarSherlock. Reparado por JakeWharton en la versión 4.0.1 (2012-03-25).

Ahora ActionBarSherlock funciona correctamente.

Cuestiones relacionadas