Andy Stampor
Andy Stampor

Reputation: 688

Fragments reset after screen orientation change

I have a MainActivity that loads a fragment in onCreate. I have another fragment that I load from the action bar. If I change the screen orientation on the first fragment, it works as expected. If I change on the second one it resets to the first fragment. This appears to be because it rebuilds everything and it puts the original fragment back into the fragment manager. I am certain there is a way to keep track of the currently displayed fragment, but I'm not sure how.

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

    // Database entries
    myDataSource = new FillupDataSource(this);
    myDataSource.open();

    // Create an instance of the MyListFragment 
    MyListFragment firstFragment = new MyListFragment();
    Bundle bundle = new Bundle();
    bundle.putSerializable("dataSource", (Serializable) myDataSource);
    firstFragment.setArguments(bundle);

    // Add the fragment to the 'fragment_container' FrameLayout
    getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, firstFragment).commit();

    getActionBar().setDisplayHomeAsUpEnabled(true);
}

I'm sure this must be something that has been done a bunch, but I am struggling to know how to search for it.

Upvotes: 5

Views: 3524

Answers (3)

Zephania Mwando
Zephania Mwando

Reputation: 118

This happens because the activity restarts when the screen orientation changes.

The option is Don't allow the activity to restart.

Do this to the AndroidManifest file for the activity. (For my case The activity is called MainActivity.)

//Specify what is done on configuration changes, this line will help you invoke configuration changes in the activity

<activity android:name=".MainActivity" android:configChanges="orientation|keyboardHidden|screenSize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

Now invoke the method below;

  @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);

        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE){

//Only if you want to do something here. If you dont want then leave it blank

            Toast.makeText(this, "Landscape Mode", Toast.LENGTH_SHORT).show();

        }else if(newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){

//Only if you want to do something here too.

            Toast.makeText(this, "Portrait Mode", Toast.LENGTH_SHORT).show();
        }
    }

Just Like Magic it works perfectly. I have tested.

Try it out and see if it works. If it doesn't request for another alternative and I will give.

Upvotes: -1

tibuurcio
tibuurcio

Reputation: 766

In an extreme case, where you don't need your application to update resources when orientation changes, you could use the following statement in your Manifest file:

<activity android:name=".MyActivity"
      android:configChanges="orientation"
      android:label="@string/app_name">

In case you're developing for Android 3.2 (API level 13) or higher you need:

android:configChanges="orientation|screenSize"

And then in your Activity you override the onConfigurationChange method:

@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);

    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        //do something...   
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        //do something...
    }
}

Note from the developers guide:

Handling the configuration change yourself can make it much more difficult to use alternative resources, because the system does not automatically apply them for you. This technique should be considered a last resort when you must avoid restarts due to a configuration change and is not recommended for most applications.

Upvotes: 2

Shane
Shane

Reputation: 972

A possible solution to this would be to save the current fragment index with instance states:

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
   //save current fragment index
}

and then restore the state

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    //have the activity switch the fragment via the saved fragment index
}

You can read more about instance states at this SO post.

Upvotes: 2

Related Questions