螢幕間的動畫元素
本指南說明如何配置螢幕間的動畫元素。該功能稱為 共用元素過渡,並於 @react-navigation/native-stack
中透過 React Native Reanimated 實作。
警告
撰寫本指南時,共用元素過渡被視為實驗功能,不建議在實際應用中使用。
事前準備
在繼續之前,請確認您的應用符合下列條件:
- 您正在使用
@react-navigation/native-stack
。共享元素轉場功能不受基於 JS 的@react-navigation/stack
支援。 - 您安裝並設定了編號 **v3.0.0 以上** 的
react-native-reanimated
。
最小範例
若要建立共享轉場,請執行下列動作:
- 使用從
react-native-reanimated
匯入的Animated
元件。 - 將相同的
sharedTransitionTag
指定給不同畫面上的元素。 - 在畫面間導覽。轉場會自動啟動。
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
,對 width
、height
、originX
、originY
和 transform
屬性進行動畫化。您可以輕鬆自訂 width
、height
、originX
和 originY
道具。也可以自訂 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
也提供對共享元素轉場的支援。您可以在 這裡 閱讀更多相關資訊。