React Native(react-navigation+Redux)页面转场动画失效求助
我之前在使用react-navigation 1.x结合Redux开发时,也踩过转场动画完全没反应的坑,结合你给出的代码片段,整理了几个最可能的原因和对应的解决办法:
1. screenInterpolator函数未完整实现
从你贴的代码来看,这个函数只写到const height = layou...就截断了——它必须返回一个具体的Animated样式对象,动画才能生效。另外你代码里的layou是拼写错误,应该是layout,这个小细节也可能导致动画失效。
比如要实现垂直滑入滑出的效果,补全后的函数应该是这样:
screenInterpolator: sceneProps => { const { position, layout, scene } = sceneProps; const thisSceneIndex = scene.index; const height = layout.initHeight; // 定义垂直平移的插值动画 const translateY = position.interpolate({ inputRange: [thisSceneIndex - 1, thisSceneIndex, thisSceneIndex + 1], outputRange: [height, 0, 0], }); // 返回最终的动画样式 return { transform: [{ translateY }] }; }
2. Redux集成时未正确绑定transitionConfig
在react-navigation 1.x结合Redux的场景下,transitionConfig必须作为StackNavigator的配置项传入,很多人会犯的错误是只在reducer里处理导航状态,却忘了把动画配置绑定到StackNavigator上。正确的集成方式如下:
import { StackNavigator, addNavigationHelpers } from 'react-navigation'; import { connect } from 'react-redux'; import { Easing, Animated } from 'react-native'; // 1. 定义StackNavigator时直接传入转场配置 const AppNavigator = StackNavigator( { // 你的路由配置 Home: { screen: HomeScreen }, Detail: { screen: DetailScreen }, }, { transitionConfig: () => ({ transitionSpec: { duration: 750, easing: Easing.out(Easing.poly(4)), timing: Animated.timing, useNativeDriver: true, }, screenInterpolator: sceneProps => { // 这里放你完整的插值函数 const { position, layout, scene } = sceneProps; const thisSceneIndex = scene.index; const width = layout.initWidth; const translateX = position.interpolate({ inputRange: [thisSceneIndex - 1, thisSceneIndex, thisSceneIndex + 1], outputRange: [width, 0, 0], }); return { transform: [{ translateX }] }; }, }), } ); // 2. Redux reducer处理导航状态 const navReducer = (state, action) => { const newState = AppNavigator.router.getStateForAction(action, state); return newState || state; }; // 3. 根组件中传递navigation prop class App extends React.Component { render() { return ( <AppNavigator navigation={addNavigationHelpers({ dispatch: this.props.dispatch, state: this.props.nav, })} /> ); } } const mapStateToProps = state => ({ nav: state.nav, }); export default connect(mapStateToProps)(App);
如果没把transitionConfig绑定到StackNavigator上,Redux集成后的导航容器会使用默认的无动画配置,自然看不到效果。
3. 尝试关闭useNativeDriver
react-navigation 1.x的早期beta版本中,useNativeDriver: true可能存在兼容性问题(比如部分动画属性在原生驱动下不支持)。你可以先把它改成false试试,如果动画生效了,说明是原生驱动的问题,后续可以调整动画属性(比如只使用transform、opacity这类支持原生驱动的属性)。
4. 检查场景索引的处理逻辑
你代码里的const toIndex = index是多余的,在screenInterpolator中,应该使用scene.index获取当前场景的索引,而非外部的index——当导航栈有多层场景时,外部的index可能不是当前场景的正确索引,会导致插值动画的输入范围错误,最终动画失效。
内容的提问来源于stack exchange,提问作者Naveen671

