如何在 React Native 中检测屏幕方向变化?

问题描述 投票:0回答:2

我正在使用

Video
中的
expo-av
来显示我的视频。我的目标是根据用户设备的方向显示视频。我正在使用
ScreenOrientation
 中的 
expo-screen-orientation
,因此我可以使用
addOrientationChangeListener
函数检测旋转。 我尝试了下面的代码,但我无法检测到方向的变化。有什么帮助我如何实现我的目标或者我的代码有什么问题吗?

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'
  },
});

react-native expo screen-orientation
2个回答
2
投票

看库方法

getOrientationAsync()

export declare function getOrientationAsync(): Promise<Orientation>;

方向定义为

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

因此,它已经返回了指代正确方向的

integer
。也许您想要做的只是删除方向之间的括号:

    let orientation = await ScreenOrientation.getOrientationAsync(); 

0
投票

您的

onOrientationChange()
功能不起作用,因为您事先锁定了方向。

方向锁定后,设备将无法检测到旋转变化。要使

addOrientationChangeListener()
正常工作,必须在异步函数上将 lockAsync 设置为 ALL 或 DEFAULT:

await ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.DEFAULT);

然后您可以通过以下方式领取零钱:

const subscription = ScreenOrientation.addOrientationChangeListener((newOrientation) => {
        console.log('this variable will show everytime the screen rotates', newOrientation);
        setOrientation(newOrientation.orientationInfo.orientation);
        
        });
© www.soinside.com 2019 - 2024. All rights reserved.