fixes NPE ActionBar.TabListener #402

merged 2 commits into from Mar 24, 2012


None yet
3 participants

gabrielittner commented Mar 23, 2012

This is a fix for Issue #391. The explanation is in the commit message.

For testing you can overwrite the FragmentTabs class in the fragment sample with the following code:

public class FragmentTabs extends SherlockFragmentActivity {

    ActionBar actionBar;

    protected void onCreate(Bundle savedInstanceState) {
        setTheme(SampleList.THEME); //Used for theme switching in samples

        actionBar = getSupportActionBar();
            .setTabListener(new TabListener<FragmentStackSupport.CountingFragment>
            (this, "simple", FragmentStackSupport.CountingFragment.class)));
            .setTabListener(new TabListener<CursorLoaderListFragment>
            (this, "contacts", LoaderCursorSupport.CursorLoaderListFragment.class)));
            .setTabListener(new TabListener<AppListFragment>
            (this, "custom", LoaderCustomSupport.AppListFragment.class)));
            .setTabListener(new TabListener<ThrottledLoaderListFragment>
            (this, "throttle", LoaderThrottleSupport.ThrottledLoaderListFragment.class)));

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;

    public TabListener(Activity activity, String tag, Class<T> clz) {
        mActivity = activity;
        mTag = tag;
        mClass = clz;

    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        if (ft == null) {
             Log.i("tabselected", "fragmenttransaction == null");
        if (mFragment == null) {
            mFragment = Fragment.instantiate(mActivity, mClass.getName());
            ft.add(, mFragment, mTag);
        } else {

    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        if (ft == null) {
            Log.i("tabunselected", "fragmenttransaction == null");
        if (mFragment != null) {

    public void onTabReselected(Tab tab, FragmentTransaction ft) {
@gabrielittner gabrielittner prevent NullPointerException at onTabSelected()
The implementation of onTabSelected() uses the instance variable 
mFragmentTransaction, which is hand over to the listeners 
onTabSelected(). At the start of an Activity, which uses a TabListener
a NullPointerException is thrown, because the FragmentTransaction is
null. The only point where a FragmentTransaction is assigned to 
mFragmentTransaction is onTabUnselected().

I guess the intended behavior is that the transaction created in
onTabUnselected() is used in onTabSelected() afterwards and the
detaching/attaching is done in the same transaction (because
onTabUnselected() doesn't call commit on the transaction itself). 

However at the start just onTabSelected() is called and not
onTabUnselected(), because there was nothing selected before. So
mFragmentTransaction is null and the Exception is thrown. I added an
if-check to  receive the FragmentTransaction the same way
onTabUnselected() does, when mFragmentTransaction is null.

JakeWharton commented Mar 23, 2012

Can you add an instanceof check to the if statement as well? If someone is using tabs inside of a regular SherlockActivity you'll get a ClassCastException on the activity start.

JakeWharton merged commit a1c502f into JakeWharton:dev Mar 24, 2012

Hi to all :)
I don't really like this solution because if you rotate your device the onTabUnselected isn't called and after rotation you'll find two "lastVisibleFragment".

I have solved using directly the FragmentManager. For example for onTabSelected:

public void onTabSelected(Tab tab, FragmentTransaction ft) {
if (ft == null) {
Log.i(TAG, "FragmentTransaction == null during Tab selection");
Fragment fragment = mFragmentManager.findFragmentByTag(mTag);
if(fragment == null) {
ft.add(, Fragment.instantiate(mActivity, mClass.getName()), mTag);
} else {

Is this a valid solution?

Thanks a lot (and thanks Jake for your great work!),

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment