react-native拖放多个项目

时间:2017-03-03 03:53:44

标签: react-native drag-and-drop

我试图创建两个可以使用react-native进行拖放的圆圈。

我本可以创建一个可以拖放的圆圈,但不知道如何单独使用两个圆圈。

这是一个可以拖放的圆圈的代码,

constructor(props){
  super(props);
  this.state = {
      pan     : new Animated.ValueXY()   //Step 1
  };

  this.panResponder = PanResponder.create({    //Step 2
      onStartShouldSetPanResponder : () => true,
      onPanResponderMove           : Animated.event([null,{ //Step 3
          dx : this.state.pan.x,
          dy : this.state.pan.y
        }]),

      onPanResponderRelease        : (e, gesture) => {} //Step 4
  });
}

这是图像

renderDraggable(){
 return (
     <View style={styles.draggableContainer}>
         <Animated.View
             {...this.panResponder.panHandlers}
             style={[this.state.pan.getLayout(), styles.circle]}>
             <Text style={styles.text}>Drag me!</Text>
         </Animated.View>
     </View>
 );
}

2 个答案:

答案 0 :(得分:0)

var transitionImageNames = ["1.png", "2.png", "3.png", "4.png"]

var count=0
for item in myList {
    var transitionImageName = transitionImageNames[count]
    item.transitionImageView.image = UIImage(named: transitionImageName)
// transitionImageName refers to 4 different images, let say 1,2,3,4.png
if (count<=3) {
    count += 1
}
}

答案 1 :(得分:0)

以下是制作物品彼此独立的方式。这个例子是在typescript中,但应该足够清楚转换为纯javascript。这里的主要想法是每个动画项目都需要自己的PanResponderInstance,一旦你更新了项目,你还需要刷新PanResponderInstance

interface State {
    model: Array<MyAnimatedItem>,
    pans: Array<Animated.ValueXY>,
    dropZone1: LayoutRectangle,
    dropZone2: LayoutRectangle,
}

public render(): JSX.Element {

    const myAnimatedItems = new Array<JSX.Element>()
    for (let i = 0; i < this.state.model.length; i++) {
        const item = this.state.model[i]
        const inst = this.createResponder(this.state.pans[i], item)
        myAnimatedItems.push(
            <Animated.View
                key={'item_' + i}
                {...inst.panHandlers}
                style={this.state.pans[i].getLayout()}>
                <Text>{item.description}</Text>
            </Animated.View>
        )
    }

    return (
        <View>
            <View onLayout={this.setDropZone1} style={styles.dropZone}>
                <View style={styles.draggableContainer}>
                    {myAnimatedItems}
                </View>
            </View>
            <View onLayout={this.setDropZone2} style={styles.dropZone}>
                <View style={styles.draggableContainer}>
                    ...
                </View>
            </View>
        </View>
    )
}

private setDropZone1 = (event: LayoutChangeEvent): void => {
    this.setState({
        dropZone1: event.nativeEvent.layout
    })
}

private setDropZone2 = (event: LayoutChangeEvent): void => {
    this.setState({
        dropZone2: event.nativeEvent.layout
    })
}

private isDropZone(gesture: PanResponderGestureState, dropZone: LayoutRectangle): boolean {
    const toolBarHeight = variables.toolbarHeight + 15 // padding
    return gesture.moveY > dropZone.y + toolBarHeight
        && gesture.moveY < dropZone.y + dropZone.height + toolBarHeight
        && gesture.moveX > dropZone.x
        && gesture.moveX < dropZone.x + dropZone.width
}

private createResponder(pan: Animated.ValueXY, item: MyAnimatedItem): PanResponderInstance {
    return PanResponder.create({
        onStartShouldSetPanResponder: () => true,
        onPanResponderMove: Animated.event([null, {
            dx: pan.x,
            dy: pan.y
        }]),
        onPanResponderRelease: (_e, gesture: PanResponderGestureState) => {
            const model = this.state.model
            const pans = this.state.pans
            const idx = model.findIndex(x => x.id === item.id)

            if (this.isDropZone(gesture, this.state.dropZone1)) {
                ... // do something with the item if needed
                // reset each PanResponderInstance
                for (let i = 0; i < model.length; i++) {
                    pans[i] = new Animated.ValueXY()
                }
                this.setState({ model: model, pans: pans })
                return
                }
            } else if (this.isDropZone(gesture, this.state.dropZone2)) {
                ... // do something with the item if needed
                    // reset each PanResponderInstance
                for (let i = 0; i < model.length; i++) {
                    pans[i] = new Animated.ValueXY()
                }
                this.setState({ model: model, pans: pans })
                return
            }

            Animated.spring(pan, { toValue: { x: 0, y: 0 } }).start()
            this.setState({ scrollEnabled: true })
        }
    })
}