2011-12-27 11 views
19

Aggiungo schede di navigazione a una barra delle azioni utilizzando il codice di esempio fornito qui: http://developer.android.com/guide/topics/ui/actionbar.html Sto utilizzando ActionBarSherlock.Null FragmentTransaction passato a TabListener.onTabSelected()

My TabListener viene copiato direttamente dai documenti.

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. 
    } 
} 

E ho istituito l'ascoltatore nella mia attività:

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

Ma l'applicazione soffia con un'eccezione di puntatore nullo perché una FragmentTransaction nulla viene passato a onTabSelected() in chi ascolta. Dovrei crearne uno da qualche parte?

Sono stato più e più volte i documenti, e sono abbastanza confuso. Riesci a vedere cosa mi sono perso?

+0

Il codice di esempio di attività in questo rapporto ActionBarSherlock bug vi aiuterà: https://github.com/JakeWharton/ActionBarSherlock/pull/402 –

risposta

15

Questo sembra essere un problema con la libreria di compatibilità (e quindi con l'associazione ActionBarSherlock). La soluzione è ignorare FragmentTransaction (null) che viene passato e ottenere il proprio. Ecco un esempio da Mark 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() è necessario in questo caso? Il documento dice "no" ma tu lo metti, perché? E nei miei test funziona solo con commit(). –

16

ho trovato il post di cui sopra Ollie utile, ma non abbastanza dettagliata. Sono riuscito a refactoring il codice fornito nella ActionBar Guide come segue (nota: bisogna fare la stessa modifica agli altri metodi implementati nel 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

Grazie per questo. È interessante notare che all'inizio ho trascurato di aggiungere la chiamata a ft.commit senza conseguenze ovvie. –

+0

Cheers @Boswell, mi sono perso anche questo e l'ho notato solo grazie al tuo commento – Dan2552

+0

Meglio della risposta di sopra. –

1

Era bug a ActionBarSherlock. Risolto da JakeWharton nella versione 4.0.1 (2012-03-25).

Ora ActionBarSherlock funziona correttamente.

Problemi correlati