Blog

Handling Screen Orientation in Android

In mobile application development screen orientation (portrait, landscape) matters a lot. Some application requires portrait, some require landscape and some requires both orientations (based on the task activity is created for).

Activity is recreated when user change orientation of the screen, If screen orientation is not handled properly, it can be very annoying for the users because activity will lose the data during the recreation process.

There are few ways to handle screen orientation and save activity/fragment data:

1. Saving and retrieving  data using onSaveInstanceState() and onRestoreInsanceState() methods.

2. Saving data using worker Fragment/Headless Fragment

Saving and retrieving data using onSaveInstanceState() and onRestoreInstanceState() method.

This is a very common way to save the data of your activity or fragment during orientation changes, you can save primitive data types and objects like Integer, String, Boolean, Parcelable object etc. in a bundle during orientation changes and read the saved data to display on the UI.
There are two methods provided in the lifecycle of Activity in Android called onSaveInstanceState() and onRestoreInstanceState(). You need to override these two methods and put the data as a key-value pair in bundle object, this data will be preserved for you while activity is being recreated. Don’t forget to recover data from bundle in onRestoreInstanceState() method. Below is the code snippet.

public class MainActivity extends AppCompatActivity {
   private final String KEY_COUNT = "count";
   private int count = 0;
   private TextView counterTextView;
   private Button clickHereButton;

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

       counterTextView = findViewById(R.id.textView);
       clickHereButton = findViewById(R.id.button_click);

       clickHereButton.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               count = count + 1;
               counterTextView.setText(String.valueOf(count));
           }
       });

   }

   @Override
   protected void onSaveInstanceState(Bundle outState) {
       super.onSaveInstanceState(outState);

       outState.putInt(KEY_COUNT, count);
   }

   @Override
   protected void onRestoreInstanceState(Bundle savedInstanceState) {
       super.onRestoreInstanceState(savedInstanceState);
      
       count = savedInstanceState.getInt(KEY_COUNT);
       counterTextView.setText(String.valueOf(count));

   }

Saving data using worker Fragment/Headless Fragment

Worker Fragment: Worker fragment or headless fragment is a fragment without an user interface that can be used as holder of your complex object data. You need not to override onCreateView() method in this fragment. Let me tell you how this fragment is useful for saving data during orientation changes.
Generally, fragments get destroyed and get recreated along with their host activity when a configuration changes/orientation changes occurs, but it has a method called setRetainInstance(boolean value), using this method inside fragment and passing true to it will prevent a fragment to be destroyed and recreated.

Below is a code snippet.

public class DetailActivity extends AppCompatActivity {

   private BlankFragment mFragment;
   private TextView detailTextView;

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

       detailTextView = findViewById(R.id.text_view_detail);

       // Getting fragment from fragment manager. It shall be null if fragment is not created previously.
       mFragment = (BlankFragment) getSupportFragmentManager().findFragmentByTag(BlankFragment.TAG);

       // Checking fragment for null and creating new instance
       if (mFragment == null) {
           mFragment = BlankFragment.newInstance();

           // Adding fragment
           getSupportFragmentManager()
                   .beginTransaction()
                   .add(mFragment, BlankFragment.TAG)
                   .commit();

           // Now we have to get data from API/DB or any other data source and have to set that into Headless fragment.
           // Here I am storing static data for example, this will be retained during orientation changes.
           mFragment.setStudent(new Student("My Name", 28));
       }


       // other code/functionality for this activity.
       detailTextView.setText(mFragment.getStudent().toString());

   }
}