使用React Navigation动画离开屏幕

toi*_*ski 13 reactjs react-native react-navigation

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

我知道阅读React Navigation文档并在Egghead.io上观看此视频(强烈建议),可以为将屏幕传递transitionConfig给a的屏幕之间的过渡定义自定义动画StackNavigator.

例如,以下代码从左侧动画定义幻灯片,幻灯片基本上是iOS默认推送动画的镜像:

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 }
)
Run Code Online (Sandbox Code Playgroud)

考虑到上面的代码,我们从屏幕导航的事实A筛选B,该screenInterpolator函数体基本上是描述动画的屏幕B应该遵循它什么时候出现(当它消失它的恢复).在这种情况下,它所说的代码是B沿X轴平移屏幕以实现幻灯片的效果.

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

  • B应该出现左滑右
  • A应该从上到下消失

toi*_*ski 12

我自己找到了答案,希望将来可以帮助别人.

我错了假设screenInterpolator描述的是屏幕只有行为B,因为实际上描述两者的动画AB.或者更好,它是interpolate功能,inputRangeoutputRange允许您描述enter(B)和leave(A)屏幕的动画.

让我们仔细看看这个片段中,同时要注意的是,interpolate功能只是创造的价值之间的关联1-1 inputRangeoutputRange(更深入的解释在这里).

const { index } = scene

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

假设:

  • B并且A是屏幕
  • 我们从导航AB
  • 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+10我们说屏幕A应该在X=0它消失时保持不变(即什么时候B会出现)

结果

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

这里描述

如果我们更改index+1to 的关联index+1 <-> -initWidth,那么屏幕A也将被翻译,因此动画:)

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

在此输入图像描述