You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native Navigation共享元素过渡动画不流畅问题求助

React Native Shared Element Transition for Text Not Working Smoothly

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?


Answer

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 13:27:29