在可拖动的Flatlist-React Native之间实现拖放功能

5
我正在为我的React-Native应用程序创建一个要求,其中我有一个空白的下拉框(当拖放一个flatlist项时,它应该转换为可拖动的flatlist),还有一个可拖动的flatlist,我必须从中拖放到空白的下拉框和反之亦然。
两个flatlists中的项目都应该有一个右侧菜单,点击后应显示将该项移动到另一个flatlist的选项。
我知道这是非常常见的情况,但由于我对React-Native相当陌生,因此我无法获得任何库或自己创建相同的内容。
我使用React-Native与Redux和Typescript,我正在使用react-native-draggable-flatlist进行Flatlist(https://github.com/computerjazz/react-native-draggable-flatlist),请让我知道是否有更好的选择。

1
我建议您使用 react-native-gesture-handler 库。如果您能提供一些设计图或最小化的代码,那就太好了! - OriHero
1
目前我还没有任何设计,非常简单。顶部将是一个空白的下拉框,底部是一个可拖动的平面列表。我必须从底部向上拖动项目,反之亦然,而且在单击所有平面列表项时应该有右侧菜单,通过它可以将项目移动到另一个平面列表中。 - Saikat Saha
2个回答

3

我已经使用 react-native-gesture-handler 创建了最小示例,如果有帮助,请告诉我:

let dropzoneHeight = 200;
let itemHeight = 60;

let FlatItem = ({ item }) => {
  let translateX = new Animated.Value(0);
  let translateY = new Animated.Value(0);
  let onGestureEvent = Animated.event([
    {
      nativeEvent: {
        translationX: translateX,
        translationY: translateY,
      },
    },
  ]);
  let _lastOffset = { x: 0, y: 0 };
  let onHandlerStateChange = event => {
    if (event.nativeEvent.oldState === State.ACTIVE) {
      _lastOffset.x += event.nativeEvent.translationX;
      _lastOffset.y += event.nativeEvent.translationY;
      translateX.setOffset(_lastOffset.x);
      translateX.setValue(0);
      translateY.setOffset(_lastOffset.y);
      translateY.setValue(0);

      //TODO here you have to check if the item is inside of container and if it is do some calculations to relocate it to your container.
    }
  };
  return (
    <PanGestureHandler
      onGestureEvent={onGestureEvent}
      onHandlerStateChange={onHandlerStateChange}>
      <Animated.View
        style={[styles.item, { transform: [{ translateX }, { translateY }] }]}>
        <Text>{item.id}</Text>
      </Animated.View>
    </PanGestureHandler>
  );
};

let data = [
  { key: 1, id: 1 },
  { key: 2, id: 2 },
  { key: 3, id: 3 },
  { key: 4, id: 4 },
];
export default class App extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <FlatList
          data={data}
          ListHeaderComponent={() => <View style={styles.dropzone} />}
          renderItem={props => <FlatItem {...props} />}
          style={{ flex: 1 }}
        />
      </View>
    );
  }
}

这里是示例代码,供您测试!


我觉得这个零食没有达到它应该有的效果...它是不是出了什么问题? - undefined
1
零食已经过时了,所以你只需要代码。 - undefined

1

使用 react-native-reanimated 的声明式 API 可以更高效地实现。

<FlatList data={new Array(10).fill(0)}
  renderItem={({item, index}) => <GestureItem key={index} item={item} />}
 />


const GestureItem = ({item})=> {
  const safex = new A.Value(0)
  const safeY = new A.Value(0)
  const draX = new Value(0)
  const dragY = new Value(0)
  const panState = new Value(State.UNDETERMINED)
  const onGestureEvent = A.event([
      {
        nativeEvent: {
          translationX: dragX,
          translationY: dragY,
          state: panState,
        },
      },
    ]);

   const transX = cond(
      eq(panState, State.ACTIVE),
      dragX,
      set(safeX, add(safeX, dragX))
    );

   const transY = cond(
      eq(panState, State.ACTIVE),
      dragY,
      set(safeY, add(safeY, dragY))
    );
  return (
    <PanGestureHandler 
      onGestureEvent={onGestureEvent}
      onHandlerStateChange={onGestureEvent}>

      <A.View style={{width: 100, height : 100, transform :[{translateX: transX}, {translateY: transY}]}} >
     </A.View>
    </PanGestureHandler>


  )
}

要交换列表项及其索引,请使用Code组件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接