kiduxa
kiduxa

Reputation: 3351

Fragment disappear when change orientation

2 days ago I posted a question: New layouts in TabHost. So I decided to create tabs with fragments instead of tabActivity. So now I have 3 tabs: tab_clients, tab_settings, tab_logut. When I run my app tab1 is showed and if I rotate my device everything works fine. My surprise comes when I change to tab2 or tab3, from these tabs when I rotate my device I get the view of tab1. This is my principal container:

public class AplicacionActivity extends FragmentActivity {

/* Tab identif */
static String TAB_clientes = "Clientes";
static String TAB_settings = "Settings";
static String TAB_logout = "Logout";

TabHost mTabHost;

ClientesActivity fragmentClientes;
SettingsActivity fragmentSettings;
LogoutActivity fragmentLogout;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_aplicacion);

    fragmentClientes = new ClientesActivity();
    fragmentSettings = new SettingsActivity();
    fragmentLogout = new LogoutActivity();

    mTabHost = (TabHost)findViewById(android.R.id.tabhost);
    mTabHost.setOnTabChangedListener(listener);
    mTabHost.setup();

    iniTab();
}   


public void iniTab() {

    Resources res = getResources(); 

    //TabHost.TabSpec: A tab has a tab indicator, content, and a tag that is used to keep track of it. 
    TabHost.TabSpec spec =  mTabHost.newTabSpec(TAB_clientes);
    mTabHost.setCurrentTab(-3);

    //TabHost.TabContentFactory: Makes the content of a tab when it is selected. 
    spec.setContent(new TabHost.TabContentFactory() {
        public View createTabContent(String tag) {
            return findViewById(android.R.id.tabcontent);
        }
    });
    spec.setIndicator(" Clientes ", res.getDrawable(R.drawable.clientes));
    mTabHost.addTab(spec);


    spec =   mTabHost.newTabSpec(TAB_settings);
    spec.setContent(new TabHost.TabContentFactory() {
        public View createTabContent(String tag) {
            return findViewById(android.R.id.tabcontent);
        }
    });
    spec.setIndicator(" Settings ",res.getDrawable(R.drawable.settings));
    mTabHost.addTab(spec);

    spec =   mTabHost.newTabSpec(TAB_logout);
    spec.setContent(new TabHost.TabContentFactory() {
        public View createTabContent(String tag) {
            return findViewById(android.R.id.tabcontent);
        }
    });
    spec.setIndicator(" Logout ",res.getDrawable(R.drawable.logouticon));
    mTabHost.addTab(spec);
}

/*
 * TabChangeListener for change the tab when is selected
 */
TabHost.OnTabChangeListener listener    =   new TabHost.OnTabChangeListener() {
    public void onTabChanged(String tabId) {
        /*Set current tab..*/
        if(tabId.equals(TAB_clientes)){
            pushFragments(tabId, fragmentClientes);
        }else if(tabId.equals(TAB_settings)){
            pushFragments(tabId, fragmentSettings);
        }else if(tabId.equals(TAB_logout)){
            pushFragments(tabId, fragmentLogout);
        }
    }
};

/*
 * insert the fragment into the FrameLayout
 */
public void pushFragments(String tag, Fragment fragment){

    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction ft = manager.beginTransaction();

    ft.replace(android.R.id.tabcontent, fragment);
    ft.commit();
}

The same happens when I click in the button inside of one of my tabs and replace the layout. When I rotate, I get the view of tab1. I have to say that I've run apps that use tabActivity instead of fragments and don't have this problem. So I'm getting a little confuse here.

Any help will be apreciated.

EDITED: The solution for this was:

1.- Create the following method on my FragmentActivity:

protected void onSaveInstanceState(Bundle bundle) {
    super.onSaveInstanceState(bundle);
    Fragment fragmentAct = this.getSupportFragmentManager().findFragmentById(android.R.id.tabcontent);
    bundle.putString("fragmentAct", fragmentoActual.getTag());
    Log.e("layout-saving",fragmentAct.getTag());
}

As you can see I'm saving in the bundle the tag of the fragment that I was seeing before I rotate my device.

2.- In my OnCreate method of my FragmentActivity I added the following code:

if (savedInstanceState != null){
   String value = savedInstanceState.getString("fragmentAct");
   establishLayout(value);
}

3.- I create a method called establishLayout:

public void establishLayout(String tagFragment){
    mTabHost.setCurrentTabByTag(tagFragment);
    Fragment fragmentoActual = this.getSupportFragmentManager().findFragmentByTag(tagFragment);
    if(fragmentoActual!=null){
        pushFragments(tagFragment, fragmentoActual);
    }
}

4.- I create the method pushFragments:

public void pushFragments(String tag, Fragment fragment){
    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction ft = manager.beginTransaction();
    ft.replace(android.R.id.tabcontent, fragment, tag);
    ft.commit();
 }

An that's it!. Every time I change the orientation of the device I dont lose the active layout! Thanks so much for the help that I got from @Yuri :)

Upvotes: 3

Views: 4046

Answers (1)

Y2i
Y2i

Reputation: 3868

On orientation change an activity is re-created. You may need a variable that keeps track of the active tab

  • save the value of the variable in onSaveInstanceState()
  • restore the value in onCreate() from savedInstanceState Bundle.
  • use restored value to properly initialize tabs

More information on handling configuration changes can be found in Android guides: http://developer.android.com/guide/components/activities.html#ConfigurationChanges

Upvotes: 1

Related Questions