gpbaculio
gpbaculio

Reputation: 5968

orientation change listener in expo react native not firing?

i want to detect the current orientation of device in expo react native, this is my code that doesn't work:

import {
 Dimensions,
} from 'react-native';
import * as ScreenOrientation from 'expo-screen-orientation';**
const App = () => {
...
useEffect(() => {
    const isPortrait = () => {
      const dimension = Dimensions.get('screen');
      return dimension.height >= dimension.width;
    };
    Dimensions.addEventListener('change', () => {
      const orientation = isPortrait() ? 'portrait' : 'landscape';
      console.log('Dimensions orientation', orientation);
    });
    ScreenOrientation.addOrientationChangeListener((e) => {
      console.log('e ', e);
    });
  }, []);

how ever when i rotate the device there is no logs so it's not firing?

Upvotes: 5

Views: 5058

Answers (10)

Anand Kumar
Anand Kumar

Reputation: 7

// App.js

 import * as ScreenOrientation from 'expo-screen-orientation';

 const webviewRef = useRef(null);

 useEffect(() => {
  const subscription =
  ScreenOrientation.addOrientationChangeListener(onOrientationChange);
    return () => {
      ScreenOrientation.removeOrientationChangeListener(subscription);
    };
  }, []);

useEffect(() => {
    ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.DEFAULT);
  }, []);

  const onOrientationChange = (event) => {
    webviewRef.current?.reload();
  };

// app.json

{
  "expo": {
    "plugins": [
      "@react-native-google-signin/google-signin",
      "expo-apple-authentication",
      [
        "expo-screen-orientation",
        {
          "initialOrientation": "DEFAULT"
        }
      ]
    ],
    "name": "My App",
    "slug": "myApp",
    "orientation": "default",
 }
}

Please keep in mind that the orientation in the app.json must be default. Moreover I also tried setting up expo-screen-orientation using app.json only and it was working but it was causing issue sometimes like when exited the app it wont work unless you remove the app from background process and run it again.

Upvotes: 0

Eugene Ihnatsyeu
Eugene Ihnatsyeu

Reputation: 1595

If you use Expo and just want your app to rotate when you rotate your phone, you need to add one line to the app mount

import * as ScreenOrientation from 'expo-screen-orientation';

...

useEffect(() => {
    ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.DEFAULT);
}, []);

Now when you rotate your phone, it will either ask you to rotate the app with an arrows icon or if you have auto-rotation enabled it will rotate your app right away.

Don't forget to reload your app in Expo Go

And don't forget to follow official Expo ScreenOrientation documentation, it's important that you app.json right

Upvotes: 1

TellMeWhy
TellMeWhy

Reputation: 315

If you're using expo bare workflow (you have access to the native code), update your AndroidManifest.xml to use fullSensor:

<activity
  android:name=".MainActivity"
  android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
  android:screenOrientation="fullSensor" <- this line
>

Upvotes: 0

Matvei
Matvei

Reputation: 1

Take a look at your app.json file and see if you have this line in there

"orientation": "portrait"

It prevents the device from changing its orientation, as it is being fixed to portrait only. Getting rid of it solved the problem for me.

Upvotes: 0

Jonathan Coletti
Jonathan Coletti

Reputation: 528

This is what worked for me full doc here (https://docs.expo.dev/versions/latest/sdk/screen-orientation/#screenorientationgetorientationasync)

npm i expo-screen-orientation

add plugins and require full screen to app.json

{
  "expo": {
    "ios": {
      "requireFullScreen": true
    },
    "plugins": [
      [
        "expo-screen-orientation",
        {
          "initialOrientation": "DEFAULT"
        }
      ]
    ]
  }
}

clean build folder and rebuild cd ios && pod deintegrate && pod setup && pod install

you are going to prob want to add a enum to tell which screen orientation it is in so this is optional

export enum ScreenOrientationEnum {
    UNKNOWN = 0,
    PORTRAIT_UP = 1,
    PORTRAIT_DOWN = 2,
    LANDSCAPE_LEFT = 3,
    LANDSCAPE_RIGHT = 4
}

Good luck :)

Upvotes: 0

benmneb
benmneb

Reputation: 2313

You're using the wrong package.

From the expo-screen-orientation docs:

Screen Orientation is defined as the orientation in which graphics are painted on the device. ... For physical device orientation, see the orientation section of Device Motion.

Upvotes: 2

cabhara
cabhara

Reputation: 481

This works for me:

const [orientation, setOrientation] = useState(
  ScreenOrientation.Orientation.PORTRAIT_UP
);

useEffect(() => {
  // set initial orientation
  ScreenOrientation.getOrientationAsync().then((info) => {
    setOrientation(info.orientation);
  });

  // subscribe to future changes
  const subscription = ScreenOrientation.addOrientationChangeListener((evt) => {
    setOrientation(evt.orientationInfo.orientation);
  });

  // return a clean up function to unsubscribe from notifications
  return () => {
    ScreenOrientation.removeOrientationChangeListener(subscription);
  };
}, []);

Upvotes: 8

Ross
Ross

Reputation: 11

I had this same issue. The listener function was never firing.

Adding expo-sensors to my project seems to have fixed the callback for me. I think expo-screen-orientation might depend on expo-sensors

Steps for adding:

  1. npx expo install expo-sensors

  2. Rebuild your expo development client. (For me that command is eas build --profile simulator, but that will depend on your eas config)

After that, the listener callback function started firing.

Here's a code snippet of where I add the listener:

  useEffect(() => {
    ScreenOrientation.addOrientationChangeListener((e) => {
      console.log(e)
    })
  }, [])

Upvotes: 1

You should set your orientation field as default in your app.json / app.config.js. The app is locked to the specified orientation if this field is set to another value.

Related doc is here: https://docs.expo.dev/versions/v46.0.0/config/app/#orientation

Upvotes: 3

JCraine
JCraine

Reputation: 1424

This is the line that doesn't do anything. Broken, bugged, POS? All of the above?

ScreenOrientation.addOrientationChangeListener((e) => {
 console.log(e);
});

Upvotes: 3

Related Questions