React Native Gesture Handler:为Swipeable组件添加半开回弹动画
实现Swipeable组件的部分展开回弹提示动画
当然可以实现这种效果,核心思路是绕过Swipeable自带的openLeft/openRight方法,直接控制其内部的动画偏移量,结合Reanimated实现自定义的部分滑动+回弹序列。下面是基于react-native-gesture-handler的Swipeable组件和Reanimated v3的具体实现:
核心实现代码
import React, { useRef, useEffect } from 'react'; import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'; import { Swipeable, GestureHandlerRootView } from 'react-native-gesture-handler'; import { useSharedValue, withTiming, runOnUI, useAnimatedReaction } from 'react-native-reanimated'; const SwipeableHintDemo = () => { const swipeableRef = useRef(null); // 控制滑动偏移量:正数向右滑(露左侧操作),负数向左滑(露右侧) const swipeOffset = useSharedValue(0); const isAnimating = useSharedValue(false); // 触发提示动画:部分展开后回弹 const triggerSwipeHint = () => { if (isAnimating.value) return; runOnUI(() => { isAnimating.value = true; // 先滑到指定偏移量(根据操作栏宽度调整,这里取100) swipeOffset.value = withTiming(100, { duration: 350 }, () => { // 停留短时间后回弹 swipeOffset.value = withTiming(0, { duration: 350 }, () => { isAnimating.value = false; }); }); })(); }; // 监听偏移量变化,同步到Swipeable内部的动画值 useAnimatedReaction( () => swipeOffset.value, (offset) => { swipeableRef.current?.animatedValue.setValue(offset); } ); // 页面加载后自动触发一次提示(可选) useEffect(() => { setTimeout(triggerSwipeHint, 1000); }, []); // 左侧操作栏 const renderLeftActions = () => ( <View style={styles.leftAction}> <Text style={styles.actionText}>删除</Text> </View> ); return ( <GestureHandlerRootView style={styles.container}> <TouchableOpacity style={styles.triggerBtn} onPress={triggerSwipeHint}> <Text>手动触发提示</Text> </TouchableOpacity> <Swipeable ref={swipeableRef} renderLeftActions={renderLeftActions} overshootLeft={false} overshootRight={false} friction={3} > <View style={styles.swipeableItem}> <Text>这是一个可滑动的项目</Text> </View> </Swipeable> </GestureHandlerRootView> ); }; const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', paddingHorizontal: 20, }, triggerBtn: { marginBottom: 20, padding: 10, backgroundColor: '#f0f0f0', borderRadius: 8, alignItems: 'center', }, swipeableItem: { backgroundColor: '#fff', padding: 20, borderRadius: 8, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 4, }, leftAction: { width: 120, backgroundColor: '#ef4444', justifyContent: 'center', alignItems: 'center', }, actionText: { color: '#fff', fontWeight: '500', }, }); export default SwipeableHintDemo;
关键细节说明
- 直接控制内部动画值:Swipeable组件内部维护了
animatedValue属性,用来驱动滑动动画,我们通过共享值swipeOffset同步这个值,实现自定义滑动位置。 - 动画序列控制:用
withTiming构建"部分滑动→停留→回弹"的动画流程,可通过调整duration参数控制动画快慢。 - 防重复触发:添加
isAnimating标记,避免动画未完成时重复触发,提升体验。 - 可选自动触发:通过
useEffect可以在页面加载后自动执行提示动画,引导用户发现滑动功能。
适配其他Swipeable组件
如果使用的是第三方Swipeable库(如react-native-swipeable),核心逻辑一致:找到组件内部控制滑动偏移的动画变量,用Reanimated的共享值驱动它的变化,实现自定义动画序列。
内容的提问来源于stack exchange,提问作者OGreeni
相关产品推荐
相关产品推荐

