跳到主要內容
版本:6.x

螢幕間的動畫元素

本指南說明如何配置螢幕間的動畫元素。該功能稱為 共用元素過渡,並於 @react-navigation/native-stack 中透過 React Native Reanimated 實作。

警告

撰寫本指南時,共用元素過渡被視為實驗功能,不建議在實際應用中使用。

事前準備

在繼續之前,請確認您的應用符合下列條件:

最小範例

若要建立共享轉場,請執行下列動作:

  1. 使用從 react-native-reanimated 匯入的 Animated 元件。
  2. 將相同的 sharedTransitionTag 指定給不同畫面上的元素。
  3. 在畫面間導覽。轉場會自動啟動。
import * as React from 'react';
import { View, Button, StyleSheet } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

import Animated from 'react-native-reanimated';

const Stack = createNativeStackNavigator();

function HomeScreen({ navigation }) {
return (
<View style={styles.container}>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
<Animated.Image
source={{ uri: 'https://picsum.photos/id/39/200' }}
style={{ width: 300, height: 300 }}
sharedTransitionTag="tag"
/>
</View>
);
}

function DetailsScreen({ navigation }) {
return (
<View style={styles.container}>
<Button title="Go back" onPress={() => navigation.goBack()} />
<Animated.Image
source={{ uri: 'https://picsum.photos/id/39/200' }}
style={{ width: 100, height: 100 }}
sharedTransitionTag="tag"
/>
</View>
);
}

export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
},
});

sharedTransitionTag 是在單一畫面內容中必須是唯一的字串,但必須與畫面間的元素相符。這個道具允許 Reanimated 識別並動畫面素,類似地在 React 中會使用告訴哪個元素在清單中屬於哪個項目位置的 key 屬性。

自訂轉場

預設情況下,轉場會使用持續時間為 500 毫秒的 withTiming,對 widthheightoriginXoriginYtransform 屬性進行動畫化。您可以輕鬆自訂 widthheightoriginXoriginY 道具。也可以自訂 transform,但這超出了本指南的範圍。

警告

自訂 SharedTransition API 尚未完成,可能會在未來版本中變更。

若要自訂轉場,您需要傳遞除 transform 之外的所有屬性。

import { SharedTransition } from 'react-native-reanimated';

const customTransition = SharedTransition.custom((values) => {
'worklet';
return {
height: withSpring(values.targetHeight),
width: withSpring(values.targetWidth),
originX: withSpring(values.targetOriginX),
originY: withSpring(values.targetOriginY),
};
});

function HomeScreen() {
return (
<Animated.Image
style={{ width: 300, height: 300 }}
sharedTransitionTag="tag"
sharedTransitionStyle={customTransition} // add this to both elements on both screens
/>
);
}

參考

您可以在 React Native Reanimated 文件 中找到完整的共享元素轉場參考。

替代方案

或者,您可以使用 react-native-shared-element 程式庫,搭配 React Navigation 繫結,在基於 JS 的 @react-navigation/stack 導覽器中實作共享元素轉場。不過,這項解決方案並未持續維護。

react-native-navigation 也提供對共享元素轉場的支援。您可以在 這裡 閱讀更多相關資訊。