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

React Native 如何实现FlatList间元素拖拽、列表重排及拖拽删除功能

React Native 跨容器拖拽+列表重排序实现方案

库选型建议

放弃react-native-draggable,该库的实现逻辑限制了拖拽元素只能在父容器范围内移动,无法满足跨FlatList拖拽的需求。推荐使用RN生态主流的手势动画组合:

  • react-native-gesture-handler:负责原生级手势识别,性能远好于JS层手势实现
  • react-native-reanimated:负责拖拽动画的原生线程渲染,避免拖拽卡顿
  • react-native-draggable-flatlist:基于前两个库封装的可拖拽重排序FlatList组件,开箱即用

各需求实现逻辑

  • 拖拽元素出FlatList范围:拖拽触发时将橙色圆点切换为根视图下的绝对定位元素,用共享值同步拖拽坐标,不受FlatList的overflow属性限制,可拖动到屏幕任意位置
  • FlatList列表项重排序:直接使用react-native-draggable-flatlist组件,仅需配置数据源、渲染项、拖拽结束回调三个核心参数即可实现列表项拖拽重排序
  • 拖拽到垃圾桶删除:提前测量垃圾桶区域的屏幕坐标范围,拖拽结束后判断当前拖拽元素的坐标是否落在该范围,命中则从数据源中删除对应项

核心代码示例

import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import Animated, { useSharedValue, useAnimatedStyle } from 'react-native-reanimated';
import DraggableFlatList from 'react-native-draggable-flatlist';

const App = () => {
  const [positionList, setPositionList] = useState([]);
  const dragX = useSharedValue(0);
  const dragY = useSharedValue(0);
  const isDragging = useSharedValue(false);
  const activeItem = useSharedValue(null);
  let trashLayout = {x:0,y:0,width:0,height:0};

  // 拖拽手势配置
  const panGesture = Gesture.Pan()
    .onStart((_, item) => {
      isDragging.value = true;
      activeItem.value = item;
    })
    .onUpdate((event) => {
      dragX.value = event.absoluteX;
      dragY.value = event.absoluteY;
    })
    .onEnd(() => {
      // 校验是否落在垃圾桶区域
      if (dragX.value > trashLayout.x && dragX.value < trashLayout.x + trashLayout.width &&
        dragY.value > trashLayout.y && dragY.value < trashLayout.y + trashLayout.height) {
        setPositionList(prev => prev.filter(i => i.id !== activeItem.value.id));
      }
      // 校验是否落在时间线区域,执行添加逻辑
      // 重置状态
      dragX.value = 0;
      dragY.value = 0;
      isDragging.value = false;
      activeItem.value = null;
    });

  return (
    <View style={{flex: 1}}>
      {/* 可重排序的positions列表 */}
      <DraggableFlatList
        data={positionList}
        onDragEnd={({data}) => setPositionList(data)}
        renderItem={({item, drag}) => (
          <GestureDetector gesture={panGesture}>
            <Animated.View>
              {/* 列表项内容 */}
              <View style={{width: 20, height: 20, backgroundColor: 'orange', borderRadius: 10}} />
            </Animated.View>
          </GestureDetector>
        )}
      />
      {/* 时间线区域 */}
      <View />
      {/* 垃圾桶区域,用onLayout获取坐标 */}
      <View onLayout={(e) => trashLayout = e.nativeEvent.layout} />
      {/* 全局悬浮的拖拽圆点,拖拽时显示 */}
      {isDragging.value && (
        <Animated.View style={[{
          position: 'absolute',
          left: dragX.value - 10,
          top: dragY.value - 10,
          width: 20,
          height: 20,
          backgroundColor: 'orange',
          borderRadius: 10,
          zIndex: 999
        }]} />
      )}
    </View>
  )
}

注意事项

安装依赖后需要按照官方指引配置原生工程:iOS端执行pod install,Android端修改MainActivity文件注册手势处理器,避免手势无响应问题。

内容的提问来源于stack exchange,提问作者Furkan Ergün

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 10:27:05