1. 给一张效果图
2. 具体代码如下
使用的就是react native里面的PanResponder,具体使用看 官网
这里主要两个知识点Animated 和 panResponder,我在componentDidMount初始 panResponder
import React from 'react';
import { PanResponder, Animated,TouchableOpacity } from 'react-native';
class Draggle extends React.Component {
super(props);
this.state = {
pan : new Animated.ValueXY(),
panResponder: null
}
componentDidMount() {
let panResponder = PanResponder.create({
onMoveShouldSetPanResponder: (evt, gestureState) => { //是否成为响应者
return true;
},
onPanResponderGrant: () => { //开始手势操作
//是Animated的方法
this.state.pan.setOffset({
x: this.state.pan.x._value,
y: this.state.pan.y._value
});
},
onPanResponderMove: Animated.event([
null,
{ dx: this.state.pan.x, dy: this.state.pan.y }
], {useNativeDriver: false}),
onPanResponderRelease: () => {
this.state.pan.flattenOffset();
}
});
this.setState({panResponder:panResponder});
}
render(){
return (
<View style={{flex:1}}>
<Animated.View
style={[styles.btnQuestion,{
transform: [{ translateX: this.state.pan.x }, { translateY: this.state.pan.y }],
}]}
{...this.state.panResponder.panHandlers }
>
<Text
style={ styles.btnText}
>
完整书籍
</Text>
</Animated.View>
</View>
)
}
}
let styles = StyleSheet.create({
btnQuestion: {
width: 65,
height: 65,
borderRadius: 50, backgroundColor: lightBlue,
position: "absolute",
zIndex: 1,
right: 10, bottom: 40
},
btnText:{
flex:1,
textAlign: 'center', textAlignVertical: 'center',
color: "#fff",
fontSize: 13,
}
})
3. 点击这个可拖拽的按钮,让onPress生效
//在onMoveShouldSetPanResponder修改一下,以此来判断用户是点击 还是 拖拽
onMoveShouldSetPanResponder: (evt, gestureState) => {
//解决PanResponder中的onPress无作用
//当大于5时才进入移动事件,有的情况下需要将onStartShouldSetPanResponderCapture设为false
if (Math.abs(gestureState.dx) > 5 || Math.abs(gestureState.dy) > 5) {
return true;
} else if (Math.abs(gestureState.dx) <= 5 || Math.abs(gestureState.dy) <= 5) {
return false;
}
},
//添加点击事件
<Text
style={styles.btnText}
onPress={() =>this.handlePress() } //自己实现这个函数吧
>
完整书籍
</Text>