gpt4 book ai didi

reactjs - 如何在 React Native 中拖放多个 View ?

转载 作者:行者123 更新时间:2023-12-03 13:58:06 24 4
gpt4 key购买 nike

我在同一位置动态添加了多个 View ,还添加了每个 View 的平移手势。所有 View 都位于同一位置,以便覆盖。我的问题是,当想要拖动最后一个 View 时,却拖动了所有 View 。如何拖动单个 View 。

在这里您可以看到其中所有 View 的 GIF。 View1、View 2 和 View 3。全部都在拖动。我想只有 View 3是可拖动的,其他 View 在拖动3完成后才拖动。

<强>1。拖动 3 - 第一次拖动。

<强>2。 Drag 2 - 第二次拖动。

<强>3。拖动 1 - 第三次拖动。

代码:

import React, { Component } from 'react';
import {
StyleSheet,
View,
Text,
PanResponder,
Animated,
Easing,
Dimensions,
Platform,
TouchableOpacity,
} from 'react-native';

let CIRCLE_RADIUS = 36;
let Window = Dimensions.get('window');
const instructions = Platform.select({
ios: 'Press Cmd+R to reload,\n' +
'Cmd+D or shake for dev menu',
android: 'Double tap R on your keyboard to reload,\n' +
'Shake or press menu button for dev menu',
});

export default class App extends Component<{}> {
constructor(props){
super(props);

this.state = {
showDraggable : true,
dropZoneValues : null,
pan : new Animated.ValueXY(),
dataDrag : [1,2,3,4],
};

this.panResponder = PanResponder.create({
onStartShouldSetPanResponder : () => true,
onPanResponderMove : Animated.event([null,{
dx : this.state.pan.x,
dy : this.state.pan.y
}]),
onPanResponderRelease : (e, gesture) => {
if(this.isDropZone(gesture)){
this.setState({
showDraggable : false
});
}else{
Animated.spring(
this.state.pan,
{toValue:{x:0,y:0}}
).start();
}
}
});
}

isDropZone(gesture){
var dz = this.state.dropZoneValues;
return gesture.moveY > dz.y && gesture.moveY < dz.y + dz.height;
}

setDropZoneValues(event){
this.setState({
dropZoneValues : event.nativeEvent.layout
});
}

render(){
return (
<View style={styles.mainContainer}>
<View
onLayout={this.setDropZoneValues.bind(this)}
style={styles.dropZone}>
<Text style={styles.text}>Drop me here!</Text>
</View>

{this.state.dataDrag.map((d, index) => (
<View key = {index} style={styles.draggableContainer}>
<Animated.View
{...this.panResponder.panHandlers}
style={[this.state.pan.getLayout(), styles.circle]}>
<Text style={styles.text}>Drag {index}</Text>
</Animated.View>
</View>
))}


</View>
);
}

renderDraggable(){
//if(this.state.showDraggable){
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>
);
//}
}
}

let styles = StyleSheet.create({
mainContainer: {
flex : 1
},
dropZone : {
height : 100,
backgroundColor:'#2c3e50'
},
text : {
marginTop : 25,
marginLeft : 5,
marginRight : 5,
textAlign : 'center',
color : '#fff'
},
draggableContainer: {
position : 'absolute',
top : Window.height/2 - CIRCLE_RADIUS,
left : Window.width/2 - CIRCLE_RADIUS,
},
circle : {
backgroundColor : '#1abc9c',
width : CIRCLE_RADIUS*2,
height : CIRCLE_RADIUS*2,
borderRadius : CIRCLE_RADIUS
},
});

GIF:

enter image description here

我想要以下结果:

enter image description here

最佳答案

有几个地方需要修改才能使其正常工作。

逐步:

  1. 您的四个圆圈拥有自己的位置。所以4Animated.ValueXY 是必需的。

    this.dataDrag = [1,2,3,4];
    this.pan = this.dataDrag.map( () => new Animated.ValueXY() );
  2. 您的 PanResponder 需要当前索引中的信息。将其拉出为一个返回函数的函数,包括索引的信息。

    getPanResponder(index) {
    return PanResponder.create({
    onStartShouldSetPanResponder: () => true,
    onPanResponderMove: Animated.event([null,{
    dx: this.pan[index].x,
    dy: this.pan[index].y
    }]),
    onPanResponderRelease : (e, gesture) => {
    if(this.isDropZone(gesture)){
    this.setState({
    showDraggable : false
    });
    }else{
    Animated.spring(
    this.pan[index],
    {toValue:{x:0,y:0}}
    ).start();
    }
    }
    });
    }
  3. 根据上述变化制定您的风格。删除不必要的外部 View ,并且还会阻止事件。

    {this.dataDrag.map((d, index) => (
    <Animated.View
    key={index}
    {...this.getPanResponder(index).panHandlers}
    style={[styles.draggableContainer, this.pan[index].getLayout(), styles.circle]}>
    <Text style={styles.text}>Drag {index}</Text>
    </Animated.View>
    ))}
  4. 使用 margin 技巧来减少仓位的计算。将 top/left 更改为 marginTop/marginLeft

    draggableContainer: {
    position : 'absolute',
    marginTop : Window.height/2 - CIRCLE_RADIUS,
    marginLeft : Window.width/2 - CIRCLE_RADIUS,
    },

最终代码:

import React, { Component } from 'react';
import {
StyleSheet,
View,
Text,
PanResponder,
Animated,
Easing,
Dimensions,
Platform,
TouchableOpacity,
} from 'react-native';

let CIRCLE_RADIUS = 36;
let Window = Dimensions.get('window');

export class App extends Component<{}> {
constructor(props){
super(props);

this.dataDrag = [1,2,3,4];
this.pan = this.dataDrag.map( () => new Animated.ValueXY() );

this.state = {
showDraggable : true,
dropZoneValues : null,
};
}

getPanResponder(index) {
return PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderMove : Animated.event([null,{
dx : this.pan[index].x,
dy : this.pan[index].y
}]),
onPanResponderRelease : (e, gesture) => {
if(this.isDropZone(gesture)){
this.setState({
showDraggable : false
});
}else{
Animated.spring(
this.pan[index],
{toValue:{x:0,y:0}}
).start();
}
}
});
}

isDropZone(gesture){
var dz = this.state.dropZoneValues;
return gesture.moveY > dz.y && gesture.moveY < dz.y + dz.height;
}

setDropZoneValues(event){
this.setState({
dropZoneValues : event.nativeEvent.layout
});
}

render(){
return (
<View style={styles.mainContainer}>
<View
onLayout={this.setDropZoneValues.bind(this)}
style={styles.dropZone}>
<Text style={styles.text}>Drop me here!</Text>
</View>

{this.dataDrag.map((d, index) => (
<Animated.View
key={index}
{...this.getPanResponder(index).panHandlers}
style={[styles.draggableContainer, this.pan[index].getLayout(), styles.circle]}>
<Text style={styles.text}>Drag {index}</Text>
</Animated.View>
))}
</View>
);
}
}

let styles = StyleSheet.create({
mainContainer: {
flex : 1
},
dropZone : {
height : 100,
backgroundColor:'#2c3e50'
},
text : {
marginTop : 25,
marginLeft : 5,
marginRight : 5,
textAlign : 'center',
color : '#fff'
},
draggableContainer: {
position : 'absolute',
marginTop : Window.height/2 - CIRCLE_RADIUS,
marginLeft : Window.width/2 - CIRCLE_RADIUS,
},
circle : {
backgroundColor : '#1abc9c',
width : CIRCLE_RADIUS*2,
height : CIRCLE_RADIUS*2,
borderRadius : CIRCLE_RADIUS
},
});

结果:

enter image description here

关于reactjs - 如何在 React Native 中拖放多个 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47551462/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com