The Widlarz Group Blog

React Native - device type dependent orientation

July 11, 2020

react native

mobile

native setup

configuration

Recently, I was tasked with setting up the app in such a way that it is available only in portrait mode on mobile phones and in both landscape AND portrait on tablets.

It is not some kind of rocket science knowledge and all this information can easily be found on the internet. And although it is true, while researching, I had to visit a few pages and learn how to do it separatly for iOS and Android.

After handling it, I decided that it would be cool to collect these few tips in one single article of some sort and share it with the rest of the world 🌍!

Let’s setup our apps!

By default, all apps created with e.g. react-native CLI switch their orientation whenever the device is rotated. It is fairly simple to block this behaviour either inside XCode (in case of iOS) by selecting desired options in Deployment Info or inside AndroidManifest.xml (in case of Android) file (located in /android/app/src/main/AndroidManifest.xml) by editing/adding android:screenOrientation="X"* to your <Activity /> tags.

* e.g. screenOrientation:"portrait", screenOrientation:"landscape" or screenOrientation:"reversePortrait" - more on it here: Android | activity element

iOS setup

Let’s open the iOS project in XCode to setup everything.

From our root project directory let’s run:

open ios/PROJECT_NAME.xcworkspace

First thing to do would be to update the Deployment Info. We need to append the target device types by iPad option and select the Requires full screen option. This way the app will fill up the entire screen 🙂.

deployment info xcode

With this being done, the second thing we need to do is to update the Info.plist file. Let’s do so by selecting it from the project navigator:

proj navigator

and update its content by setting the Supported interface orientations key to an array with only portrait value and add Supported interface orientations (iPad) key with the array containing desired orientations for tablets as the value:

supported plist

Now, when we run the app on an iPhone, it will be set to portrait only at all times:

.

On an iPad on the other hand, it will be changing the orientations:

Android setup

Now let’s handle the Android for a change.

To start with, we need to update our activities setup in AndroidManifest.xml in android folder (android/app/src/main/AndroidManifest.xml).

If you have just initialized your React Native app, you should have only one activity tag, but e.g. when you added a custom splash screen already, you would have e.g. two. What you need to do is to update every activity tag so it either has android:screenOrientation="unspecified" set or no such option at all (unspecified is the default value), like so:

<application
      android:name=".MainApplication"
      ...
      android:theme="@style/AppTheme">

      <activity
          android:name=".SplashActivity"
          ...
          android:screenOrientation="unspecified"> <-- HERE
          ...
      </activity>

      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:screenOrientation="unspecified"> <-- HERE

    ...

Next step would be to add another few config files. Let’s create new folders inside android/app/src/main/res* along with a new .xml files inside each.

Folders should be named in such a way that they start with values - the only difference between them should be the ending, specifying the “dimensions” of the display (you can read more about it in Android Developers documentation*).

The file names are up to you 🙂. I decided to go with tablets.xml

* Android | Providing resources

android res

Each tablets.xml file that we have just created, should carry a value for XML boolean type*

* XML Resource - bool

Let’s call it e.g. portrait_only and set it accordingly for device type/dimensions:

  1. In tablets.xml from values folder (phones):
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="portrait_only">true</bool>
</resources>
  1. In tablets.xml from values-sw600dp and values-xlarge folders (tablets):
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="portrait_only">false</bool>
</resources>

Having done these two steps, we need to handle one last thing ➡️ override the onCreate method in the android/app/src/main/java/com/PROJECT_NAME/MainActivity.java and call setRequestedOrientation, like so:

...
import android.os.Bundle;
import android.content.pm.ActivityInfo;
...

public class MainActivity extends ReactActivity {
  ...
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (getResources().getBoolean(R.bool.portrait_only)) {
      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }
  }

  ...
}

Also, the important thing to do is to make sure that we have all the necessary imports:

import android.os.Bundle;
import android.content.pm.ActivityInfo;

That’s it! Now we have device type dependent orientation available and set up for our app. Let’s quickly test if everything works as it should:

There’s also a repo a with bare React Native app set up the same way as in this article, so if you need it, you can look the code up here - GitHub repo


Written by Daniel Grychtoł.