Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fragment on Screen Rotation

I have added a viewpager to an activity which contains two page.

In onCreate of activity I add fragments to a fragmentAdapter:

public void onCreate(Bundle savedInstanceState)
{
    ......

    FragmentAdapter fragmentAdapter = new FragmentAdapter
    (
        getSupportFragmentManager(),
        new Fragment[]{FragmentGame.builder(id), FragmentComments.builder(id)},
        new String[]{getString(R.string.gameInfo), getString(R.string.comments)}
    );

    ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);
    viewPager.setAdapter(fragmentAdapter);

public static FragmentGame builder(long id)
{
    FragmentGame fragmentGame = new FragmentGame();

    // fragmentGame.id = id;

    Bundle bundle = new Bundle();
    bundle.putLong(Constants.EXTRA_ID, id);
    fragmentGame.setArguments(bundle);

    return fragmentGame;
}

First time that activity is created the onCreateView of fragment is called as it's expected.

The strange behaviour is when the screen is rotated for the first time the onCreateView of fragment is called twice but the second call only has the correct id and for the first call id is 0.

On second screen rotation, onCreateView is called three times and again only the last one has id.

By more screen rotation, onCreateView calls increase.

I found some related question about fragment and screen rotation but I can't figure out why this happens and how to do it the right way.

----- UPDATE ------

The ID problem is solved as I replaced bundle with direct value setting.

like image 841
Ali Avatar asked Oct 07 '13 07:10

Ali


People also ask

What happens to fragment when screen is rotated?

Background. When you rotate your device and the screen changes orientation, Android usually destroys your application's existing Activities and Fragments and recreates them. Android does this so that your application can reload resources based on the new configuration.

What happens if activity with retained fragment is rotated?

Fragments — Scenario 3: Activity with retained Fragment is rotated. The fragment is not destroyed nor created after the rotation because the same fragment instance is used after the activity is recreated. The state bundle is still available in onActivityCreated .

How do I change the orientation of a fragment?

Use the following code line in the fragment where you want a specific (in this case portrait) orientation. getActivity(). setRequestedOrientation( ActivityInfo. SCREEN_ORIENTATION_PORTRAIT);


2 Answers

If you don't want to reload your fragment on orientation change, write following for the activity in which you are loading the fragment in manifest file.

<activity
            android:name="your activity name"
            android:configChanges="orientation|screenSize" // add this to your activity
            android:label="@string/app_name">
 </activity>
like image 105
kapil thadani Avatar answered Oct 20 '22 14:10

kapil thadani


Every time you rotate your device you are creating a new fragment and adding it to the FragmentManager.

All of your previously created fragments are still in the FragmentManager therefore the count increases by one each time.

If you wish to retain a value in your fragment, you need to store it in the arguments otherwise any values it contains would be lost when the system re-creates the fragment.

public static FragmentGame builder(long id) {
 Bundle args = new Bundle();
 args.putInt("id", id);
 fragmentGame f = new fragmentGame();
 f.setArguments(args);
}

Rather than creating a new fragment, I suspect you really want to retrieve your previously created one when you rotate the device. use getSupportFragmentManager().findFragmentById() or getSupportFragmentManager().findFragmentByTag() to do this.

Edit: Extra code

    // Add fragment to the manager
    FragmentTransaction trans=getSupportFragmentManager().beginTransaction();
    trans.add(f,"myTag");
    trans.commit();

    // retrieve the fragment
    Fragment f= getSupportFragmentManager().findFragmentByTag("myTag");

Just attempt to retrieve the fragment, if the value is null, create a new fragment and add it to the manager otherwise use the retrieved one.

like image 41
Kuffs Avatar answered Oct 20 '22 15:10

Kuffs