React Native, 使用纵向模式检测屏幕旋转变化

8

我正在使用React Native应用程序中的肖像模式。但是,我想捕获屏幕的旋转事件。 有没有方法可以实现这一点?

谢谢...


欢迎,Sinan!你尝试过 https://github.com/yamill/react-native-orientation 吗? - itnAAnti
5个回答

17

这个函数可能会对你有所帮助
创建一个useOrientation.js文件

import {useEffect, useState} from 'react';
import {Dimensions} from 'react-native';

export function useOrientation(){
  const [orientation, setOrientation] = useState("PORTRAIT");

  useEffect(() => {
    Dimensions.addEventListener('change', ({window:{width,height}})=>{
      if (width<height) {
        setOrientation("PORTRAIT")
      } else {
        setOrientation("LANDSCAPE")
    
      }
    })

  }, []);

  return orientation;
}

9
useEffect中使用Dimensions.removeEventListener来移除监听函数,以避免可能引发的内存问题。https://reactnative.dev/docs/dimensions - sandaru.ny
2
Dimensions.removeEventListener 已被弃用。请使用 addEventListener() 返回的事件订阅上的 remove() 方法。 - d_coder

9
为了补充前面的答案,如果你只是想让你的应用程序具有响应性,使用useWindowDimensions()会更容易。 https://reactnative.dev/docs/usewindowdimensions 只需在您的根组件中添加以下代码:
const SCREEN_WIDTH = useWindowDimensions().width;
const SCREEN_HEIGHT = useWindowDimensions().height;
return (
        <View style={{ width: SCREEN_WIDTH, minHeight: SCREEN_HEIGHT}} >
            //the rest of your app
        </View>
    );

谢谢,我使用了之前的答案并进行了修改,不再在useEffect中使用addEventListener,而是添加了条件if (width<height)并将宽度和高度添加到useEffect的依赖数组中。它运行良好,您有其他想法吗? - Oliver D
1
调用钩子两次是浪费,你可以使用解构代替 const { width, height } =... - Dominic
对我来说不起作用。如果我旋转手机,应用程序仍保持纵向模式(这是我想要的),但报告的高度和宽度仍然相同,而我希望它们交换位置。问题是如何检测应用程序的屏幕旋转,即使设置为保持纵向模式? - Hans Bouwmeester

3

使用 useWindowDimensions

import {useWindowDimensions} from "react-native"
export function useIsLandscape() {
  const {height, width} = useWindowDimensions()
  return width > height
}

一个快速简便的本地钩子实现,适用于2022年。

3

useDeviceOrientation: 将返回一个对象,每当设备更改方向时将更新该对象的值为"true"或"false"。

import { useDeviceOrientation } from "@react-native-community/hooks";
useDeviceOrientation返回的示例对象:
{
  "landscape": false,
  "portrait": true,
}

我们可以对对象进行解构:
const { landscape } = useDeviceOrientation();

然后我们可以使用它:

height: landscape ? "100%" : "30%"

这里有一个问题,我发现如果设备在钩子开始时处于横向模式,则返回{portrait: true, landscape: false}。请参见https://github.com/react-native-community/hooks/issues/210。 - baralong

3

好的,您有几个选项。 您可以使用 Dimensions API https://reactnative.dev/docs/dimensions

您可以添加一个Dimensions.change监听器,并且可以执行以下操作:

function isPortrait() {
  const dim = Dimension.get("screen")
  return dim.height >= dim.width
}

function isLandscape() {
  const dim = Dimension.get("screen")
  return dim.width >= dim.height
}

现在添加监听维度更改的功能。
Dimensions.addEventListener("change", () => {
// orientation has changed, check if it is portrait or landscape here
})

另一种可能性是使用可用的方向包之一,例如https://github.com/wonday/react-native-orientation-locker


1
谢谢回答。但是“Dimensions.addEventListener”不起作用。我的应用程序只能在纵向模式下工作。因此,当我翻转屏幕时,它不会进入“landSpace”模式,而我也不想使用“landSpace”模式。 - Sinan Coskun
在iOS上,您需要允许您的应用程序旋转。在XCode中,您需要进入目标,然后在“部署信息”->“设备方向”中启用应用程序应支持的方向。 对于Android,您将需要修改AndroidManifest文件并在activity标记上设置screenOrientation。更多信息请参见:https://medium.com/building-with-react-native/how-to-lock-device-orientation-for-react-native-apps-android-ios-2x02-952c42cb51b1 - Daniel Dimitrov
1
但是如果我需要允许应用程序旋转,那么如何防止应用程序在横向模式下呈现自身?我想保持纵向模式,但仍然能够检测到用户将手机旋转90度。 - Hans Bouwmeester

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接