Ollie C
Ollie C

Reputation: 28519

Null FragmentTransaction being passed to TabListener.onTabSelected()

I'm adding navigation tabs to an action bar using the sample code provided here: http://developer.android.com/guide/topics/ui/actionbar.html I'm using ActionBarSherlock.

My TabListener is copied directly from the docs.

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

And I set up the listener in my activity:

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

But the app blows up with a null pointer exception because a null FragmentTransaction is being passed to onTabSelected() in the listener. Should I be creating one somewhere?

I've been over and over the docs, and I'm pretty confused. Can you see what I've missed?

Upvotes: 19

Views: 6790

Answers (4)

Frantic
Frantic

Reputation: 1179

I found the solution here: https://github.com/JakeWharton/ActionBarSherlock/issues/482

Double-check if your host activity is derived from SherlockFragmentActivity

Upvotes: 15

Mark
Mark

Reputation: 541

I found Ollie's post above helpful, but not detailed enough. I managed to refactor the code provided in the ActionBar Guide as follows (note: you have to make the same change to the other methods implemented in the 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);
    }
}

Upvotes: 16

Sash0k
Sash0k

Reputation: 750

It was bug at ActionBarSherlock. Fixed by JakeWharton in version 4.0.1 (2012-03-25).

Now ActionBarSherlock works correct.

Upvotes: 1

Ollie C
Ollie C

Reputation: 28519

This seems to be an issue with the compatibility library (and therefore by association ActionBarSherlock). The solution is to ignore the (null) FragmentTransaction that is passed in, and get your own. Here's an example from 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

Upvotes: 15

Related Questions