Search code examples
androidandroid-listviewandroid-actionbaractionbarsherlock

ActionBarSherlock Tabs Initially displays another tab's content before loading its own


I'm having a bit of trouble with tabs and ActionBarSherlock.

Basically, I have a menu that has 3 buttons that load up a single Activity. This Activity is a SherlockListActivity and has 3 tabs that will be selected depending on which item in the menu was used to start the Activity.

The problem I'm having is that when I load the first tab through the menu, go back to the menu, and load the third tab from the menu, it'll show the first tab as selected--and then load the third tab.

Here's some specifics about my implementation:

Activity is:

public class MyActivity extends SherlockListActivity implements ActionBar.TabListener

The following is called in onCreate to set a global String named mode:

    String dToken = null;

    Bundle extras = getIntent().getExtras();
    if (extras != null) {
        dToken = extras.getString("value");
    }
    mode = dToken;

ABS and tabs are initialized in onCreate with the following:

    ActionBar ab = getSupportActionBar();
    ab.setDisplayHomeAsUpEnabled(true);

    //Sets the ActionBarSherlock Tabs
    getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    ActionBar.Tab leftTab = getSupportActionBar().newTab();
    leftTab.setText("First");
    leftTab.setTabListener(this);

    ActionBar.Tab midTab = getSupportActionBar().newTab();
    midTab.setText("Second");
    midTab.setTabListener(this);

    ActionBar.Tab rightTab = getSupportActionBar().newTab();
    rightTab.setText("Third");
    rightTab.setTabListener(this);

Now to set which tab is selected (using the mode variable obtained from the second block of code from above), this is in the end of onCreate:

    if (mode.equals("first"))
        ab.addTab(leftTab, true);
    else ab.addTab(leftTab, false);             
    if (mode.equals("second"))
        ab.addTab(midTab, true);
    else ab.addTab(midTab, false); 
    if (mode.equals("third"))
        ab.addTab(rightTab, true);
    else ab.addTab(rightTab, false);

So let's say that in the menu, I click the first the first menu item. It'll load up the results of the first tab. I go back to the menu and click the third menu item and it'll load the results of the first tab for a few seconds, and then switch to the results of the third tab.

This wasn't a problem when each menu item loaded separate activities but I merged them all because the code between the three activities were nearly identical.

I tried something like calling this.finish whenever the back button was used so that I could flush out the activity but that didn't work.


Solution

  • Take a look at my Tab Listener,

    private class MyTabListener implements ActionBar.TabListener {
        @Override
        public void onTabSelected(Tab tab, FragmentTransaction ft) {
    
            switch (tab.getPosition()) {
            case 0:
    
                if (frag1 == null) {
                    // If not, instantiate and add it to the activity
                    frag1 = Fragment.instantiate(getApplicationContext(),
                            PackagesFragment.class.getName());
                    ft.add(android.R.id.content, frag1, "Feeds");
                } else {
                    // If it exists, simply attach it in order to show it
                    ft.show(frag1);
                }
                return;
    
            case 1:
    
                if (frag2 == null) {
                    // If not, instantiate and add it to the activity
                    frag2 = Fragment.instantiate(getApplicationContext(),
                            BlogsFragment.class.getName());
                    ft.add(android.R.id.content, frag2, "Profile");
                } else {
                    // If it exists, simply attach it in order to show it
                    ft.show(frag2);
                }
                return;
            case 2:
    
                if (frag3 == null) {
                    // If not, instantiate and add it to the activity
                    frag3 = Fragment.instantiate(getApplicationContext(),
                            GalleryFragment.class.getName());
                    ft.add(android.R.id.content, frag3, "Gallery");
                } else {
                    // If it exists, simply attach it in order to show it
                    ft.show(frag3);
                }
                return;
    
            }
    
        }
    
        @Override
        public void onTabUnselected(Tab tab, FragmentTransaction ft) {
            // TODO Auto-generated method stub
    
                // Detach the fragment, because another one is being attached
                switch (tab.getPosition()) {
                case 0:
                    ft.hide(frag1);
                    return;
                case 1:
                    ft.hide(frag2);
                    return;
                case 2:
                    ft.hide(frag3);
                    return;
    
    
                }
    
    
        }
    
        @Override
        public void onTabReselected(Tab tab, FragmentTransaction ft) {
            // TODO Auto-generated method stub
        }
    }