clamum
clamum

Reputation: 1364

Android: Upon Rotation, Current Fragment Disappears (How to Save State)

I've tried searching here and on Google and just cannot figure this out. Any help would be greatly appreciated.

So my application consists of a MainActivity and multiple Fragments, and it utilizes a NavigationDrawer. The drawer has been implemented just as it is in the Android documentation for NavDrawer (using the Support Library v4). Clicking on one of the several ListView Items on the left drawer loads a Fragment like below (this code is in MainActivity):

Fragment fragment = MyAmmunitionFragment.newInstance();

FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
               .replace(R.id.content_frame, fragment, MyAmmunitionFragment.Tag)
               .addToBackStack(Tag)
               .commit();

mLvLeftDrawer.setItemChecked(position, true);

setTitle(getString(R.string.my_ammunition));

mDrawerLayout.closeDrawer(mLvLeftDrawer);

The problem I'm having is when I rotate the screen. Say one of my Fragments is loaded, like the one above. If the screen is rotated, the current Fragment disappears and my "homescreen" Fragment is displayed. By the way, when the app loads a "homescreen" Fragment is loaded by the Activity, as below:

private void populateMainSummaryFragment(int position, boolean addToBackStack) {
    Log.v(Tag, "populateMainSummaryFragment()");

    Fragment fragment = MainSummaryFragment.newInstance();

    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction()
                                                             .replace(R.id.content_frame, fragment);

    if (addToBackStack) {
        fragmentTransaction.addToBackStack(Tag);
    }

    fragmentTransaction.commit();

    mLvLeftDrawer.setItemChecked(position, true);

    //setTitle(getString(R.string.app_name));

    mDrawerLayout.closeDrawer(mLvLeftDrawer);
}

I have been able to save any text inputted by the user by overriding onSaveInstanceState() in the Fragment and storing the data in SharedPreferences, then loading from the preferences in the Fragment's onResume() method.

My question is: How do I save the current Fragment itself when the screen rotates (NOT just the data the user may have inputted)?

Currently, I decided to save the current Fragment's tag in SharedPrefs, and then in the MainActivity's "onResume()" method read from SharedPrefs and load the Fragment using the same code as above. It's not working for some reason, and to me, it feels like a hacky/crappy solution. But, if that's what's gotta be done, so be it. It ain't working though, at the moment.

If I can ask a second question, how can I save user inputted data when the screen rotates, and NOT when the user merely navigates to another Fragment? Right now, the user inputted data is saved no matter if the screen is rotated or the Fragment navigated away from. I assume it's just logic and not some specific method call(s), but I'm not seeing the solution.

Thanks a ton for any help!

Upvotes: 2

Views: 1592

Answers (1)

Yash Sampat
Yash Sampat

Reputation: 30601

Save the name of the current Fragment class in the Activity's onSaveInstanceState(). In the Activity's onCreate(),

if(savedInstanceState != null){

    /* get the name of the Fragment class that was previously saved
     * and load that Fragment, instead of loading HomeFragment. */

}

Now, to check whether the state change is due to rotation, use the following:

Create a class member

private int myOrientation;

In your onCreate(), use

Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
myOrientation = display.getOrientation();

Afterwards, override the method onConfigurationChanged(), and here you can check if the orientation has actually changed or not:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    if(newConfig.orientation != myOrientation){
        // perform rotation-specific tasks
    }
    super.onConfigurationChanged(newConfig);
}

Try this. This will work.

Upvotes: 3

Related Questions