我遇到了同样的问题,并通过使用来自react-native-reanimated的Animated.View解决了它。 (来自标准react-native包的Animation.View也可能有效,但我没有检查过)。我不需要使用Animated值,我仍然只是使用状态中的实际值,并且它起作用了。
,
如果您直接从 React Native 使用 Animated.Value
+ Animated.View
,您会没事的。
遇到了同样的问题并使用 Animated.Value
类字段解决了它(在您的情况下,我猜您会为此使用 useState
,因为功能 + useEffect
来设置Animated.Value
在 props.rotation
中发生变化),然后将其作为 Animated.View
传递到
transform = [{ rotate: animatedRotationValue }]
这是它的类组件形式的片段:
interface Props {
rotation: number;
}
class SomethingThatNeedsRotation extends React.PureComponent<Props> {
rotation = new Animated.Value(0);
rotationValue = this.rotation.interpolate({
inputRange: [0,2 * Math.PI],outputRange: ['0deg','360deg'],});
render() {
this.rotation.setValue(this.props.rotation);
const transform = [{ rotate: this.rotationValue }];
return (
<Animated.View style={{ transform }} />
);
}
}
请注意,在我的示例中,我也有插值,因为我的输入以弧度为单位,我希望它以度为单位。
,
这是我完成的处理旋转的组件。当应用程序锁定为纵向时,它将根据设备方向旋转其子项。我确定这可以清理一些,但它对我的目的有效。
import React,{useState,useEffect,useRef} from 'react';
import {Animated,Easing,View,StyleSheet} from 'react-native';
import {Orientation} from '../utility/constants';
import OrientationManager from '../utility/orientation';
const OrientedView = (props) => {
const getRotation = useRef((newOrientation) => {
switch (newOrientation) {
case Orientation.LANDSCAPE_LEFT:
return 90;
case Orientation.LANDSCAPE_RIGHT:
return -90;
default:
return 0;
}
});
const {duration = 100,style} = props;
const initialized = useRef(false);
const [orientation,setOrientation] = useState();
const [rotate,setRotate] = useState();
const [containerStyle,setContainerStyle] = useState(styles.containerStyle);
// Animation kept as a ref
const rotationAnim = useRef();
// listen for orientation changes and update state
useEffect(() => {
OrientationManager.getDeviceOrientation((initialOrientation) => {
const initialRotation = getRotation.current(initialOrientation);
// default the rotation based on initial orientation
setRotate(initialRotation);
rotationAnim.current = new Animated.Value(initialRotation);
setContainerStyle([
styles.containerStyle,{
transform: [{rotate: `${initialRotation}deg`}],},]);
initialized.current = true;
// set orientation and trigger the first render
setOrientation(initialOrientation);
});
OrientationManager.addDeviceOrientationListener(setOrientation);
return () =>
OrientationManager.removeDeviceOrientationListener(setOrientation);
},[]);
useEffect(() => {
if (initialized.current === true) {
const rotation = getRotation.current(orientation);
setRotate(
rotationAnim.current.interpolate({
inputRange: [-90,90],outputRange: ['-90deg','0deg','90deg'],}),);
Animated.timing(rotationAnim.current,{
toValue: rotation,duration: duration,easing: Easing.ease,useNativeDriver: true,}).start();
}
},[duration,orientation]);
// FIXME: This is causing unnessary animation outside of the oriented view. Disabling removes the scale animation.
// useEffect(() => {
// applyLayoutAnimation.current();
// },[orientation]);
useEffect(() => {
if (initialized.current === true) {
setContainerStyle([
styles.containerStyle,{
transform: [{rotate}],]);
}
},[rotate]);
if (initialized.current === false) {
return <View style={[containerStyle,style]} />;
}
return (
<Animated.View style={[containerStyle,style]}>
{props.children}
</Animated.View>
);
};
const styles = StyleSheet.create({
containerStyle: {flex: 0,justifyContent: 'center',alignItems: 'center'},});
export default OrientedView;
,
这是一个错误,因为当 rotate
的值更新时,旋转应该会改变。一种解决方法是将视图的 key
属性也设置为旋转值。
例如:
return (
<View
key={rotate} // <~~~ fix!
style={{transform: [{rotate}]}}
>
{props.children}
</View>
)
我找到了这个解决方案 here。
本文链接:https://www.f2er.com/3170131.html