使用React Navigation对离开屏幕进行动画处理

时间:2018-11-14 16:54:21

标签: reactjs react-native react-navigation

我正在开发一个使用React Navigation的React Native应用程序 管理屏幕之间的路由。

我知道在Egghead.io上阅读React Navigation documentation和观看this video(强烈建议),可以为将transitionConfig属性传递到{{1 }}。

例如,以下代码定义了一个从左滑动动画,该动画基本上是iOS默认推送动画的镜像:

StackNavigator

考虑到上面的代码以及我们正在从屏幕const TransitionConfig = () => ({ screenInterpolator: ({ layout, position, scene }) => { const { index } = scene const { initWidth } = layout const translateX = position.interpolate({ inputRange: [index - 1, index, index + 1], outputRange: [-initWidth, 0, 0], }) return { transform: [{ translateX }], } } }) const MyNavigator = createStackNavigator( { A: {screen: ScreenA}, B: {screen: ScreenB}, }, { transitionConfig: TransitionConfig } ) 导航到屏幕A的事实,B函数体基本上是描述屏幕screenInterpolator应该遵循的动画何时显示(消失时恢复原状)。在这种情况下,代码就是说要沿X轴平移屏幕B,以实现 slide in 效果。

是否可以为正在消失的屏幕(在我们的示例中为屏幕B)定义动画?我想定义这样的东西:

  • A应该出现从左向右滑动
  • B应该消失从顶部滑动到底部

1 个答案:

答案 0 :(得分:10)

我自己找到了答案,希望以后能对某人有所帮助。

假设screenInterpolator仅描述屏幕B的行为是错误的,因为实际上是描述AB的动画。或更妙的是,interpolate函数与inputRangeoutputRange一起使您可以为进入(B和离开(A)描述动画屏幕。

让我们更仔细地看一下此代码段,请记住interpolate函数只是在inputRangeoutputRange的值之间建立1-1关联(更深入的解释{ {3}})。

const { index } = scene

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

假设:

  • BA是屏幕
  • 我们正在从A导航到B
  • width(B) = width(A) = 320
  • width(deviceScreen) = 320
  • initWidth = 320

说明

  • index-1代表将要出现的屏幕(屏幕B),并且已映射到-initWidth。以此,我们要说将要显示的屏幕(屏幕B)应进行X转换(尊重视口),其值等于其宽度。因此它将从X = 320(即屏幕外部)开始播放动画
  • index代表将要出现的屏幕,但一旦出现(仍然是屏幕B)。将其映射到0就是说屏幕B出现后应该位于位置X = 0
  • index + 1代表屏幕将消失。这就是导致我出错的原因。一开始我以为B仍然是并且仅,但是只是由于B->C之类的导航而消失了。但是,从我们的A->B的角度来看,屏幕A将会消失!因此,两种思路都是正确的,这都是关于从不同角度看待事物。因此,将index+1映射到0就是说屏幕A将会消失时(即X=0出现时)应该停留在B

结果

这是上面的代码实现的动画。如您所见,由于A的关联,屏幕index+1 <-> 0保留在原处(没有翻译,因此屏幕A没有动画)。

here

如果我们将index+1的关联更改为index+1 <-> -initWidth,则屏幕A也会被翻译并因此具有动画效果:)

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

Description here