React Native Navigation共享元素过渡动画不流畅问题求助
I'm trying to implement the simplest shared element transition for text, but it's not working at all— the transition is completely unsmooth. I've checked the official docs and followed the steps, but nothing seems to work. Here's my current code:
App.js
import {NavigationContainer} from '@react-navigation/native'; import * as React from 'react'; import {createSharedElementStackNavigator} from 'react-navigation-shared-element'; import DetailScreen from './DetailScreen'; import ListScreen from './ListScreen'; const Stack = createSharedElementStackNavigator(); const App = ({navigation}) => { return ( <NavigationContainer> <Stack.Navigator initialRouteName="List" screenOptions={{ headerShown: false, }}> <Stack.Screen name="MainScreen" component={ListScreen} /> <Stack.Screen name="DetailScreen" component={DetailScreen} options={navigation => ({ headerBackTitleVisible: false, cardStyleInterpolator: ({current: {progress}}) => { return { cardStyle: { opacity: progress, }, }; }, })} sharedElements={route => { const {data} = route.params; console.log(data); return [ { id: `item.${data.id}`, animation: 'move', resize: 'stretch ', align: 'center-top', }, ]; }} /> </Stack.Navigator> </NavigationContainer> ); }; export default App;
ListScreen.js
import * as React from 'react'; import {Text, TouchableOpacity, View} from 'react-native'; import {SharedElement} from 'react-native-shared-element'; const ListScreen = props => { const {navigation} = props; const persons = [ { id: '1', name: 'Earnest Green', }, { id: '2', name: 'Winston Orn', }, { id: '3', name: 'Carlton Collins', }, { id: '4', name: 'Malcolm Labadie', }, { id: '5', name: 'Michelle Dare', }, ]; return ( <View style={{ flex: 1, padding: 50, }}> {persons.map(person => { return ( <TouchableOpacity onPress={() => navigation.navigate('DetailScreen', {data: person})}> <SharedElement id={`item.${person.id}`}> <Text style={{padding: 20, fontSize: 15, marginTop: 5}}> {person.name} </Text> </SharedElement> </TouchableOpacity> ); })} </View> ); }; export default ListScreen;
DetailScreen.js
import * as React from 'react'; import {Text, View} from 'react-native'; import {SharedElement} from 'react-navigation-shared-element'; const DetailScreen = ({route}) => { const {data} = route.params; return ( <View style={{flex: 1, justifyContent: 'flex-start', alignItems: 'center'}}> <SharedElement id={`item.${data.id}`}> <Text style={{fontSize: 22}}>{data.name}</Text> </SharedElement> </View> ); }; export default DetailScreen;
The transition animation is completely unsmooth— how can I fix this?
Let's walk through the issues in your code that are causing the shared element transition to fail or be unsmooth:
1. Fix Route Name Mismatch
In App.js, you set initialRouteName="List" but named the ListScreen's route "MainScreen". This mismatch causes initial routing issues that can break the shared element trigger. Update the screen name to match:
<Stack.Screen name="List" component={ListScreen} />
2. Correct Syntax Error in Shared Elements Config
You have an extra space in the resize property value ('stretch ' instead of 'stretch'). This invalid value will prevent the animation from being parsed correctly:
// Change this resize: 'stretch ', // To this resize: 'stretch',
3. Remove Conflicting Card Opacity Animation
The cardStyleInterpolator you added to the DetailScreen is fading the entire card in, which overlaps with the shared element transition and creates a jarring visual effect. Remove this config temporarily until your shared element transition works as expected:
// Delete this options block (or comment it out) options={navigation => ({ headerBackTitleVisible: false, cardStyleInterpolator: ({current: {progress}}) => { return { cardStyle: { opacity: progress, }, }; }, })}
4. Align Base Layout Styles for Shared Elements
The Text component in ListScreen has padding: 20 and marginTop:5, while the one in DetailScreen doesn't. This causes a sudden layout jump during transition. Wrap your Text elements in a View to keep the container dimensions consistent, then adjust only the Text size:
ListScreen.js update:
<SharedElement id={`item.${person.id}`}> <View style={{padding: 20, marginTop: 5}}> <Text style={{fontSize: 15}}>{person.name}</Text> </View> </SharedElement>
DetailScreen.js update:
<SharedElement id={`item.${data.id}`}> <View style={{padding: 20, marginTop: 5}}> <Text style={{fontSize: 22}}>{data.name}</Text> </View> </SharedElement>
5. Verify Dependencies Are Installed Correctly
Make sure you have all required dependencies installed and linked:
npm install react-native-shared-element react-navigation-shared-element
For iOS, run cd ios && pod install && cd .. to link the native modules. For Android, no extra linking is needed, but ensure your React Native version is compatible with the dependency versions.
After making these changes, your text shared element transition should work smoothly.
内容的提问来源于stack exchange,提问作者Benjamin Jones

