React Navigation:如何使用StackNavigator在屏幕上提供动画值

时间:2018-09-27 07:07:11

标签: react-native react-navigation

我想在场景更改时为屏幕组件制作动画。可以在屏幕上提供动画值吗?

class ScreenWithAnimation extends Component {
  render() {
    const { position } = this.props;
    const { index } = this.props.navigation.state;

    const style = {
        opacity: position.interpolate({
            inputRange: [index - 1, index, index + 1],
            outputRange: [0, 1],
        })
    };

    return (
        <View>
            <Text style={style}>Some text!</Text>
        </View>
    );
  }
}

2 个答案:

答案 0 :(得分:0)

您可以通过创建自己的transitionerConfig来做到这一点。我通过调整react-navigation代码本身的几行来实现以下目标。

let MyTransition = (props) => {
  const { layout, position, scene } = props;
  if (!layout.isMeasured) {
    return forInitial(props);
  }
  const interpolate = getSceneIndicesForInterpolationInputRange(props);

  if (!interpolate) return { opacity: 0 };

  const { first, last } = interpolate;
  const index = scene.index;
  const opacity = position.interpolate({
    inputRange: [first, first + 0.01, index, last - 0.01, last],
    outputRange: ([0, 1, 1, 0.85, 0])
});

  const width = layout.initWidth;
  const translateX = position.interpolate({
    inputRange: ([first, index, last]),
    outputRange: I18nManager.isRTL
        ? ([-width, 0, width * 0.3])
        : ([width, 0, width * -0.3]),
  });
  const translateY = 0;

  return {
    opacity,
    transform: [{ translateX }, { translateY }],
  };
};

const MyCustomTransition = (props) => {
  const { layout, position, scene } = props;
  const { index } = scene;

  const height = layout.initHeight;
  const translateY = position.interpolate({
    inputRange: [index - 1, index, index + 1],
    outputRange: [height, 0, 0],
  });

  const opacity = position.interpolate({
    inputRange: [index - 1, index - 0.99, index],
    outputRange: [0, 1, 1],
  });

  return { opacity, transform: [{ translateY }] }
};

const TransitionConfiguration = (param)=> {
  return {
    transitionSpec: {
      duration: 400,
      easing: Easing.out(Easing.poly(4)),
      timing: Animated.timing,
    },
    screenInterpolator: (sceneProps) => {
      const {scene} = sceneProps;
      const {route} = scene;
      const params = route.params || {};
      const transition = params.transition || 'default';
      return {
        myCustomTransition: MyCustomTransition(sceneProps),
        default: MyTransition(sceneProps),
      }[transition];
    }
  }
};

现在您可以在StackNavigator中指定上述配置,如下所示:-

const MainNavigation = StackNavigator(
  {
    //routes
  },
  {
     transitionConfig: () => TransitionConfiguration(),
     // other config
  }
)

答案 1 :(得分:0)

我为找到这个解决方案和成功而迷失了很多时间!! 我们需要使用来自“@react-navigation/stack”的 useCardAnimation 钩子 它可以返回提供当前屏幕动画值上下文的钩子 - 看代码:


import React from 'react'

const Start = () => {
const {current} = useCardAnimation()
const animateStyle = {
        transform: [{scale: current.progress.interpolate({inputRange: [0, 1], outputRange: [0, 1]})}]
    }

return (
        <Animated.View style={[styles.container, animateStyle]}>
            <Text>It work!!!!!!!!!!!!!!</Text/>
        </Animated.View>
    )
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#78bdd0',
    }
})

export default Start,