效果图:
![](https://img.haomeiwen.com/i4731495/c16e3cb72a2b0b41.gif)
相关代码:
'use strict';
import React, { Component } from 'react';
import {
View,
PanResponder,
StyleSheet,
} from 'react-native';
import PropTypes from 'prop-types';
import ViewUtil from '../utils/View';
/**
* 使用方法
*
*
* import PanResponderView from "../components/panResponder";
*
<PanResponderView
toachStyle={styles.toachStyle}
/>
*/
let _previousLeft = 0;
let _previousTop = 0;
let lastLeft = 0;
let lastTop = 0;
export default class Radio extends Component {
static defaultProps = {
PanSize: 80,
PanStyle: {
width: 80,
height: 80,
borderRadius: 80 / 2,
backgroundColor: 'yellow',
position: 'absolute',
},
defalutStyle:{
backgroundColor:"yellow"
},
};
static propTypes = {
PanSize: PropTypes.number, //手势驱动宽度
PanDom: PropTypes.element, //手势区自定义dom
PanStyle: PropTypes.any, //手势最外层view样式
toachStyle: PropTypes.any, //触摸反馈样式
defalutStyle:PropTypes.any //默认状态下的样式
};
constructor(props) {
super(props);
this.state = {
style: this.props.defalutStyle,
}
this.onStartShouldSetPanResponder = this.onStartShouldSetPanResponder.bind(this);
this.onMoveShouldSetPanResponder = this.onMoveShouldSetPanResponder.bind(this);
this.onPanResponderGrant = this.onPanResponderGrant.bind(this);
this.onPanResponderMove = this.onPanResponderMove.bind(this);
this.onPanResponderEnd = this.onPanResponderEnd.bind(this);
}
//用户开始触摸屏幕的时候,是否愿意成为响应者;
onStartShouldSetPanResponder(evt, gestureState) {
return true;
}
//在每一个触摸点开始移动的时候,再询问一次是否响应触摸交互;
onMoveShouldSetPanResponder(evt, gestureState) {
return true;
}
// 开始手势操作。给用户一些视觉反馈,让他们知道发生了什么事情!
onPanResponderGrant(evt, gestureState) {
this.setState({
style:
{
...StyleSheet.flatten(this.props.toachStyle),
left: _previousLeft,
top: _previousTop,
}
});
}
// 最近一次的移动距离为gestureState.move{X,Y}
onPanResponderMove(evt, gestureState) {
const { PanSize, toachStyle } = this.props;
_previousLeft = lastLeft + gestureState.dx;
_previousTop = lastTop + gestureState.dy;
if (_previousLeft <= 0) {
_previousLeft = 0;
}
if (_previousTop <= 0) {
_previousTop = 0;
}
if (_previousLeft >= ViewUtil.size.width - PanSize) {
_previousLeft = ViewUtil.size.width - PanSize;
}
if (_previousTop >= ViewUtil.size.height - PanSize) {
_previousTop = ViewUtil.size.height - PanSize;
}
//实时更新
this.setState({
style:
{
...StyleSheet.flatten(toachStyle),
left: _previousLeft,
top: _previousTop,
}
});
}
// 用户放开了所有的触摸点,且此时视图已经成为了响应者。
// 一般来说这意味着一个手势操作已经成功完成。
onPanResponderEnd(evt, gestureState) {
lastLeft = _previousLeft;
lastTop = _previousTop;
this.changePosition();
}
/**
根据位置做出相应处理
**/
changePosition() {
const { PanSize,defalutStyle } = this.props;
if (_previousLeft + PanSize / 2 <= ViewUtil.size.width / 2) {
//left
_previousLeft = lastLeft = 0;
this.setState({
style:
{
...StyleSheet.flatten(defalutStyle),
left: _previousLeft,
top: _previousTop,
}
});
} else {
_previousLeft = lastLeft = ViewUtil.size.width - PanSize;
this.setState({
style:
{
...StyleSheet.flatten(defalutStyle),
left: _previousLeft,
top: _previousTop,
}
});
}
}
componentWillMount(evt, gestureState) {
this._panResponder = PanResponder.create({
onStartShouldSetPanResponder: this.onStartShouldSetPanResponder,
onMoveShouldSetPanResponder: this.onMoveShouldSetPanResponder,
onPanResponderGrant: this.onPanResponderGrant,
onPanResponderMove: this.onPanResponderMove,
onPanResponderRelease: this.onPanResponderEnd,
onPanResponderTerminate: this.onPanResponderEnd,
});
}
render() {
const { PanDom, PanStyle } = this.props;
return (
<View
{...this._panResponder.panHandlers}
style={[PanStyle, this.state.style]}>
{PanDom}
</View>
);
}
}
网友评论