Reputation: 2062
I'm using Video
from expo-av
to display my videos. My goal is to display the video depending on the Orientation of the device of the user. I'm using ScreenOrientation
from expo-screen-orientation
so i can detect the rotation using the addOrientationChangeListener
function.
I tried my code below but i can't detect the change of the orientation. Any Help of how can i achieve my goal or what's wrong in my code?
import React, { Component } from 'react';
import {
StyleSheet,
View,
TouchableOpacity,
Image,
Text,
Alert,
ScrollView,
Dimensions
} from 'react-native';
import { Video } from 'expo-av';
import * as ScreenOrientation from 'expo-screen-orientation';
import NavigationHelper from '../../../../Helpers/NavigationHelper';
export default class VideoScreen extends Component {
constructor(props) {
super(props);
/* enum Orientation {
UNKNOWN = 0,
PORTRAIT_UP = 1,
PORTRAIT_DOWN = 2,
LANDSCAPE_LEFT = 3,
LANDSCAPE_RIGHT = 4
} */
this.state = {
orientation: 1,
};
}
async componentDidMount() {
await this.detectOrientation();
this.subscription = ScreenOrientation.addOrientationChangeListener(this.onOrientationChange);
/* if (ScreenOrientation.Orientation.LANDSCAPE) {
this.changeScreenLandscapeOrientation();
} */
}
async componentWillUnmount() {
await ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.PORTRAIT);
ScreenOrientation.removeOrientationChangeListener(this.subscription);
// this.changeScreenPortraitOrientation();
}
onOrientationChange = async (orientation) => {
console.log('orientation changed');
if (orientation === 3 || orientation === 4) {
await ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.LANDSCAPE);
} else {
await ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.PORTRAIT);
}
this.setState({ orientation });
};
detectOrientation= async () => {
let orientation = await ScreenOrientation.getOrientationAsync();
const screen = Dimensions.get('screen');
if (orientation === 0) {
orientation = screen.width > screen.height ? ScreenOrientation.Orientation.LANDSCAPE : ScreenOrientation.Orientation.PORTRAIT;
}
this.setState({ orientation });
console.log(orientation);
};
render() {
const { route } = this.props;
const { videoUri } = route.params;
if (!videoUri) {
NavigationHelper.back();
}
return (
<ScrollView style={styles.container}>
<Video
source={{ uri: videoUri }}
rate={1.0}
volume={1.0}
isMuted={false}
resizeMode={Video.RESIZE_MODE_CONTAIN}
shouldPlay
isLooping
useNativeControls
style={{ width: 300, height: 300, alignSelf: 'center' }}
orientationChange={this.onOrientationChange}
/>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#000000',
flexDirection: 'column'
},
});
Upvotes: 2
Views: 4447
Reputation: 21
Your onOrientationChange()
function its not working because you are locking the orientation before hand.
Once the orientation is locked the device is unable to detect the rotation change. For addOrientationChangeListener()
to work the lockAsync has to be set on ALL or DEFAULT on an async function:
await ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.DEFAULT);
Then you can pick up the change with:
const subscription = ScreenOrientation.addOrientationChangeListener((newOrientation) => {
console.log('this variable will show everytime the screen rotates', newOrientation);
setOrientation(newOrientation.orientationInfo.orientation);
});
Upvotes: 0
Reputation: 347
Look at the library method getOrientationAsync()
export declare function getOrientationAsync(): Promise<Orientation>;
The orientation definition is
export declare enum Orientation {
UNKNOWN = 0,
PORTRAIT_UP = 1,
PORTRAIT_DOWN = 2,
LANDSCAPE_LEFT = 3,
LANDSCAPE_RIGHT = 4
}
So, it already returns the integer
that refers to the correct orientation. Maybe what you want to do is just remove the brackets between the orientation:
let orientation = await ScreenOrientation.getOrientationAsync();
Upvotes: 2