react native 使用PanResponder實現 上划下划手勢



使用reactnative的panResponder組件
實現手勢響應的一系列函數
componentWillMount() {
this._panResponder = PanResponder.create({
onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder,
onMoveShouldSetPanResponder: this._handleMoveShouldSetPanResponder,
onPanResponderGrant: this._handlePanResponderGrant,
onPanResponderMove: this._handlePanResponderMove,
onPanResponderRelease: this._handlePanResponderEnd,
onPanResponderTerminate: this._handlePanResponderEnd,
});
this._previousHeight = 0;
this._circleStyles = {
style: {
height: this._previousHeight,
backgroundColor: 'green',
}
};
}
重點來寫這兩個函數
 onPanResponderMove: this._handlePanResponderMove,
響應過程中觸發
this.show來表示圖片view層的顯示狀態
如果this.show == false,手指向下滑動圖片層高度漸變跟隨手指,如果this.show == true手指向下滑動則不響應,
向上滑動也是同理
_handlePanResponderMove = (e: Object, gestureState: Object) =>{
if(this.show && gestureState.dy < 0 || !this.show && gestureState.dy > 0){
this._circleStyles.style.height = this._previousHeight + gestureState.dy;
this._updateNativeStyles();
}

}


onPanResponderRelease: this._handlePanResponderEnd,
響應結束時觸發
以50為界限,如果this.show == false,向下滑動距離超過50則顯示,show = true,小於50或向上滑動不響應
如過this.show == true,向上滑動距離超過50隱藏,show = false,小於50或向下滑動不響應
_handlePanResponderEnd = (e: Object, gestureState: Object) =>{
this._unHighlight();

if( gestureState.dy <= -50 && this.show){
this._circleStyles.style.height = 0;
this.show = false;
this._updateNativeStyles();
}else if( gestureState.dy >= 50 && !this.show){
this._circleStyles.style.height = height;
this.show = true;
this._updateNativeStyles();
}else{
this._circleStyles.style.height = this.show?height:0;
this._updateNativeStyles();
}
this._previousHeight = this._circleStyles.style.height;
}


效果如圖:

完整代碼如下:
'use strict';

import React,{Component} from 'react';
import {
PanResponder,
StyleSheet,
View,
Button,
Image,
Dimensions,
} from 'react-native';


var img = require('../img/r.jpg');
let {width,height} = Dimensions.get('window');
class PanResponderExample extends Component{
constructor(props){
super(props);
this.statics ={
title: 'PanResponder Sample',
description: 'Shows the use of PanResponder to provide basic gesture handling.',
};
this._panResponder = {};
this._previousHeight = 0;
this._circleStyles = {};
this.circle = (null : ?{ setNativeProps(props: Object): void });
this.show = false;
}

componentWillMount() {
this._panResponder = PanResponder.create({
onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder,
onMoveShouldSetPanResponder: this._handleMoveShouldSetPanResponder,
onPanResponderGrant: this._handlePanResponderGrant,
onPanResponderMove: this._handlePanResponderMove,
onPanResponderRelease: this._handlePanResponderEnd,
onPanResponderTerminate: this._handlePanResponderEnd,
});
this._previousHeight = 0;
this._circleStyles = {
style: {
height: this._previousHeight,
backgroundColor: 'green',
}
};
}

componentDidMount(){
this._updateNativeStyles();
}

render(){
return (
<View
style={styles.container}
{...this._panResponder.panHandlers}>
<View style={styles.circle}
ref={(circle) => {
this.circle = circle;
}}
>
<Image
source={img}
style = {{width:200,height:200,borderRadius:100}}

/>
</View>
</View>
);
}

_highlight(){
this._circleStyles.style.backgroundColor = 'rgba(0,0,0,0.03)';
this._updateNativeStyles();
}

_unHighlight(){
this._circleStyles.style.backgroundColor = 'transparent';
this._updateNativeStyles();
}

_updateNativeStyles(){
this.circle && this.circle.setNativeProps(this._circleStyles);
}

_handleStartShouldSetPanResponder = (e: Object, gestureState: Object): boolean => {
// Should we become active when the user presses down on the circle?
return true;
}

_handleMoveShouldSetPanResponder = (e: Object, gestureState: Object): boolean =>{
// Should we become active when the user moves a touch over the circle?
return true;
}

_handlePanResponderGrant = (e: Object, gestureState: Object) =>{
this._highlight();
}
_handlePanResponderMove = (e: Object, gestureState: Object) =>{
if(this.show && gestureState.dy < 0 || !this.show && gestureState.dy > 0){
this._circleStyles.style.height = this._previousHeight + gestureState.dy;
this._updateNativeStyles();
}

}
_handlePanResponderEnd = (e: Object, gestureState: Object) =>{
this._unHighlight();

if( gestureState.dy <= -50 && this.show){
this._circleStyles.style.height = 0;
this.show = false;
this._updateNativeStyles();
}else if( gestureState.dy >= 50 && !this.show){
this._circleStyles.style.height = height;
this.show = true;
this._updateNativeStyles();
}else{
this._circleStyles.style.height = this.show?height:0;
this._updateNativeStyles();
}
this._previousHeight = this._circleStyles.style.height;
}
}

var styles = StyleSheet.create({
circle: {
justifyContent:'center',
width:width,
height:height,
position:'absolute',
top:0,
left:0,
elevation:10,
alignItems:'center',

},
container: {
flex: 1,
backgroundColor:'pink',
alignItems:'stretch',
flexDirection:'column',
elevation:1,
},
});

module.exports = PanResponderExample;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM