ReactNative手势上滑隐藏下滑显示

一、实现效果

ReactNative手势上滑隐藏下滑显示_第1张图片

二、实现方式

1 使用RN的panResponder组件来实现手势滑动

2 在constructor中初始可变组件的属性值和stytle

    constructor(props) {
            super(props);
            this.thresholdMin = 5;
            this.thresholdMax = 20;
            this.sapceInitHeight = 130;
            this.spaceHeight = 130;
            this.imageInitHeight = 61;
            this.imageHeight = 61;
            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: autoHeight(130),
    	        justifyContent: 'center',
    	        alignItems: 'center',
    	        backgroundColor: color.transparent,
    	    },
    	    image: {
    	        opacity:1,
    	        width: autoSize(238),
    	        height: autoSize(61),
    	        marginBottom: autoHeight(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);
        }

三、React Native 触摸事件处理详解

参考:https://www.race604.com/react-native-touch-event/

你可能感兴趣的:(React,Native)