ReactNative手势上滑隐藏下滑显示
2019-04-03 本文已影响16人
Huangrong_000
一、实现效果
demo.gif二、实现方式
1 使用RN的panResponder组件来实现手势滑动###
2 在constructor中初始可变组件的属性值和stytle###
constructor(props) {
super(props);
this.thresholdMin = 5;
this.thresholdMax = 20;
this.sapceInitHeight = 330;
this.spaceHeight = 330;
this.imageInitHeight =180;
this.imageHeight = 180;
this.imageInitOpacity = 1;
this.imageOpacity = 1;
this._spaceStyles = {};
this.space = (null: ?{ setNativeProps(props: Object): void });
this._imageStyles = {};
this.image = (null: ?{ setNativeProps(props: Object): void });
this.show = true;
}
3 在render中绑定this._panResponder手势处理handler,并通过ref关联组件对应的stytle###
render() {
return (
<View style={styles.container} {...this._panResponder.panHandlers}>
<View style={styles.space}
ref={(space) => {
this.space = space;
}}
>
<Image style={styles.image}
ref={(image) => {
this.image = image;
}}
source={require('../../../res/img/home/space_img.png')}/>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: color.transparent,
},
space: {
height: 330,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: color.transparent,
},
image: {
opacity:1,
width: 238,
height: 180,
marginBottom: 35,
resizeMode: 'contain'
}
});
4 在componentWillMount实现手势响应的一系列函数,并给stytle属性重新赋值###
componentWillMount() {
this._panResponder = PanResponder.create({
// 要求成为响应者:
//this.refs[RefsConstant.HOME_DEV_LIST].setRefreshFunc(false);
onStartShouldSetPanResponder: (evt, gestureState) => false,
onStartShouldSetPanResponderCapture: (evt, gestureState) => false,
onMoveShouldSetPanResponder: (evt, gestureState) => false,
onMoveShouldSetPanResponderCapture: (evt, gestureState) => {
if (Math.abs(gestureState.dx) < this.thresholdMin && Math.abs(gestureState.dy) < this.thresholdMin) {
return false;
} else {
if ((this.show && gestureState.dy < 0) || (!this.show && gestureState.dy > 0)) {
return true;
} else {
return false;
}
}
},
onPanResponderGrant: (evt, gestureState) => {
// 开始手势操作。给用户一些视觉反馈,让他们知道发生了什么事情!
console.log('onPanResponderGrant');
// gestureState.{x,y} 现在会被设置为0
},
onPanResponderMove: (evt, gestureState) => {
// 最近一次的移动距离为gestureState.move{X,Y}
console.log('onPanResponderMove');
console.log('滑动参数:dx='+gestureState.dx +',dy='+gestureState.dy + '可见吗='+this.show);
// 从成为响应者开始时的累计手势移动距离为gestureState.d{x,y}
if ((this.show && gestureState.dy < 0) || (!this.show && gestureState.dy > 0)) {
this._spaceStyles.style.height = this.sapceInitHeight + gestureState.dy;
this._imageStyles.style.height = this._spaceStyles.style.height * this.imageHeight / this.spaceHeight;
this._imageStyles.style.opacity = this._spaceStyles.style.height / this.spaceHeight;
if (this._spaceStyles.style.height >= 0 && this._spaceStyles.style.height <= this.spaceHeight) {
this._updateNativeStyles();
}
}
},
//是否可以释放响应者角色让给其他组件
onPanResponderTerminationRequest: (evt, gestureState) => true,
onPanResponderRelease: (evt, gestureState) => {
// 用户放开了所有的触摸点,且此时视图已经成为了响应者。
console.log('onPanResponderRelease');
// 一般来说这意味着一个手势操作已经成功完成。
if (gestureState.dy <= -1 * this.thresholdMax && this.show) {
this._spaceStyles.style.height = 0;
this._imageStyles.style.height = 0;
this._imageStyles.style.opacity = 0;
this.show = false;
console.log('隐藏');
this._updateNativeStyles();
} else if (gestureState.dy >= this.thresholdMax && !this.show) {
this._spaceStyles.style.height = this.spaceHeight;
this._imageStyles.style.height = this.imageHeight;
this._imageStyles.style.opacity = this.imageOpacity;
this.show = true;
console.log('显示');
this._updateNativeStyles();
} else {
this._spaceStyles.style.height = this.show ? this.spaceHeight : 0;
this._imageStyles.style.height = this.show ? this.imageHeight : 0;
this._imageStyles.style.opacity = this.show ? this.imageOpacity : 0;
console.log('不变');
this._updateNativeStyles();
}
this.sapceInitHeight = this._spaceStyles.style.height;
this.imageInitHeight = this._imageStyles.style.height;
this.imageInitOpacity = this._imageStyles.style.opacity;
},
onPanResponderTerminate: (evt, gestureState) => {
// 另一个组件已经成为了新的响应者,所以当前手势将被取消。
console.log('onPanResponderTerminate');
},
onShouldBlockNativeResponder: (evt, gestureState) => {
// 返回一个布尔值,决定当前组件是否应该阻止原生组件成为JS响应者
// 默认返回true。目前暂时只支持android。
return true;
},
});
this._spaceStyles = {
style: {
height: this.sapceInitHeight,
}
};
this._imageStyles = {
style: {
height: this.imageInitHeight,
opacity: this.imageInitOpacity,
}
};
5 在componentDidMount实现更新组件stytle的函数###
componentDidMount() {
this.updateNativeStyles();
}
updateNativeStyles() {
this.space && this.space.setNativeProps(this._spaceStyles);
this.image && this.image.setNativeProps(this._imageStyles);
}