我正在开发一个使用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
应该消失从顶部滑动到底部答案 0 :(得分:10)
我自己找到了答案,希望以后能对某人有所帮助。
假设screenInterpolator
仅描述屏幕B
的行为是错误的,因为实际上是描述A
和B
的动画。或更妙的是,interpolate
函数与inputRange
和outputRange
一起使您可以为进入(B
和离开(A
)描述动画屏幕。
让我们更仔细地看一下此代码段,请记住interpolate
函数只是在inputRange
和outputRange
的值之间建立1-1关联(更深入的解释{ {3}})。
const { index } = scene
const translateX = position.interpolate({
inputRange: [index - 1, index, index + 1],
outputRange: [-initWidth, 0, 0],
})
假设:
B
和A
是屏幕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
没有动画)。
如果我们将index+1
的关联更改为index+1 <-> -initWidth
,则屏幕A
也会被翻译并因此具有动画效果:)
const translateX = position.interpolate({
inputRange: [index - 1, index, index + 1],
outputRange: [initWidth, 0, -initWidth],
})