react native 手勢驅動封裝 類似 ios的AssistiveTouch
摘要:
效果圖:
pan.gif
相關程式碼:
'use strict';
import React, { Component } from 'react';
import {
View,
PanRespon...
效果圖:

pan.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> ); } }