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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 11:17:40