Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActionBar Tabs with support library

The problem I'm having is the Action Bar will not show on Android 2.3.7, but will work fine on 4.x+. The rest of my application works fine with the support v7 and v4 libraries, it's just this one area which is giving me trouble.

Here is what it should look like, as seen on 4.3:

Android 4.3 view

And here is what it looks like on 2.3.7:

Android 2.3.7 view

Inside my onCreate method (of the class which inherits from ActionBarActivity), I have this:

    // setup action bar for tabs
    ActionBar actionBar = getSupportActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    actionBar.setDisplayHomeAsUpEnabled(true);
    actionBar.setDisplayShowTitleEnabled(true);


    Tab tab = actionBar.newTab()
            .setText(R.string.details)
            .setTabListener(new TabListener<DetailsFragmentOne>(
                    this, "one", DetailsFragmentOne.class));
    actionBar.addTab(tab);

    tab = actionBar.newTab()
        .setText(R.string.grades)
        .setTabListener(new TabListener<DetailsFragmentTwo>(
                this, "one", DetailsFragmentTwo.class));
    actionBar.addTab(tab);

And here is my TabListener, an inner class:

/**
 * This is copied almost verbatim from <a href="http://developer.android.com/guide/topics/ui/actionbar.html#Tabs">the ActionBar Tabs API Guide</a>.
 * @param <T>
 */
public 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(Tab tab, FragmentTransaction ft) {
        FragmentTransaction sft = ((FragmentActivity) mActivity).getSupportFragmentManager().beginTransaction();
        mFragment = getSupportFragmentManager().findFragmentByTag(mTag);
        // 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());
            // calling commit() here because we're not using the provided FragmentTransaction
            sft.replace(android.R.id.content, mFragment, mTag).commit();
        } else {
            // If it exists, simply attach it in order to show it
            // calling commit() here because we're not using the provided FragmentTransaction
            sft.replace(android.R.id.content, mFragment).commit();
        }
    }

    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        FragmentTransaction sft = ((FragmentActivity) mActivity).getSupportFragmentManager().beginTransaction();
        mFragment = getSupportFragmentManager().findFragmentByTag(mTag);
        if (mFragment != null) {
             // calling commit() here because we're not using the provided FragmentTransaction
            sft.replace(android.R.id.content, mFragment).commit();
        }
    }

    public void onTabReselected(Tab tab, FragmentTransaction ft) {          
        FragmentTransaction sft = ((FragmentActivity) mActivity).getSupportFragmentManager().beginTransaction();
        mFragment = getSupportFragmentManager().findFragmentByTag(mTag);
        if (mFragment != null) {
             // calling commit() here because we're not using the provided FragmentTransaction
            sft.replace(android.R.id.content, mFragment).commit();
        }
    }

}

I have seen these two other questions and attempted to implement the answers, but am still having the issue.

  • Implementing a TabListener using the Support Library

  • Implementing ActionBar tabs with v4 Fragments API

edit: As requested, the theme which is being applied is simply the support library's AppCompat.Light.DarkActionBar theme with no overrides, seen below:

<style name="Theme.MyTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
</style>
like image 897
Kyle Falconer Avatar asked Aug 13 '13 21:08

Kyle Falconer


1 Answers

If you remove the background of your DetailFragment, the ActionBar and Tabs actually appear behind the DetailFragment. Instead of android.R.id.content, create your own container in your main layout and use R.id.yourcontent when calling replace in your FragmentTransaction. By making this change, it worked for me on 2.3.3 and 4+.

It appears that 2.3.3 adds the ActionBar to the root view element where 4+ is adding it outside of the root view.

sft.replace(R.id.yourcontent, mFragment).commit();
like image 98
blackcj Avatar answered Sep 23 '22 00:09

blackcj