2011-12-27 3 views
19

Я добавляю вкладки навигации в панель действий, используя приведенный здесь пример кода: http://developer.android.com/guide/topics/ui/actionbar.html Я использую ActionBarSherlock.Null FragmentTransaction передается в TabListener.onTabSelected()

My TabListener копируется непосредственно из документов.

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

И я настраивал слушатель в моей деятельности:

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

Но приложение взрывает с нулевым указателем исключением, так как нулевое FragmentTransaction настоящего времени передается onTabSelected() в слушателе. Должен ли я где-нибудь создавать?

Я был над и над документами, и я довольно смущен. Вы видите, что я пропустил?

+0

Пример кода активности в данном отчете ActionBarSherlock ошибка поможет: https://github.com/JakeWharton/ActionBarSherlock/pull/402 –

ответ

15

Это, кажется, проблема с библиотекой совместимости (и, следовательно, путем объединения ActionBarSherlock). Решение состоит в том, чтобы игнорировать (нулевое) FragmentTransaction, которое передается и получать ваши собственные. Вот пример из Марк Мерфи:

 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() необходим в этом случае? Док говорит «нет», но вы так выразились, почему? И в моих тестах он работает только с commit(). –

16

Я нашел пост Олли выше полезно, но не достаточно детализированы. Мне удалось реорганизовать код, предоставленный в ActionBar Guide следующим образом (примечание: вы должны сделать то же самое изменение других методов, реализованных в 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

Спасибо за это. Интересно, что сначала я забыл добавить вызов ft.commit без каких-либо очевидных последствий. –

+0

Cheers @Boswell, я пропустил это тоже и только заметил его благодаря вашему комментарию – Dan2552

+0

Лучше, чем выше ответ. –

1

Это была ошибка в ActionBarSherlock. Исправлено JakeWharton в версии 4.0.1 (2012-03-25).

Теперь ActionBarSherlock работает правильно.