1. 程式人生 > >React Native PanResponder API呼叫順序詳解

React Native PanResponder API呼叫順序詳解

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

const SCREEN_WIDTH = Dimensions.get('window').width;
const SCREEN_HEIGHT = Dimensions.get('window').height;

export default class RefresherListView extends Component {
    _panResponder = null;//觸控響應控制代碼

    constructor(props) {
        super(props);
    }

    componentWillMount() {
        this._panResponder = PanResponder.create({
            onShouldBlockNativeResponder: () => false,//是否應該阻止原生觸控事件響應

            onStartShouldSetPanResponderCapture: this.onStartShouldSetPanResponderCapture,//所以如果一個父檢視要防止子檢視在觸控開始時成為響應器,它應該有一個 onStartShouldSetResponderCapture 處理程式,返回 true
            onStartShouldSetPanResponder: this.onStartShouldSetPanResponder,//這個檢視是否在觸控開始時想成為響應器

            onMoveShouldSetPanResponderCapture: this.onMoveShouldSetPanResponderCapture,
            onMoveShouldSetPanResponder: this.onMoveShouldSetPanResponder,//當檢視不是響應器時,該指令被在檢視上移動的觸控呼叫:這個檢視想“宣告”觸控響應嗎?

            onPanResponderTerminationRequest: () => true,//其他的東西想成為響應器。這種檢視應該釋放應答嗎?返回 true 就是允許釋放
            onPanResponderTerminate: () => null,//響應器已經從該檢視抽離了。可能在呼叫onResponderTerminationRequest 之後被其他檢視獲取,也可能是被作業系統在沒有請求的情況下獲取了(發生在 iOS 的 control center/notification center)

            //Api 呼叫順序
            onPanResponderGrant: this.onPanResponderGrant,//檢視現在正在響應觸控事件。這個時候要高亮標明並顯示給使用者正在發生的事情
            onResponderReject: this.onResponderReject,//當前有其他的東西成為響應器並且沒有釋放它

            onPanResponderStart: this.onPanResponderStart,
            onPanResponderMove: this.handlePanResponderMove,
            onPanResponderEnd: this.onPanResponderEnd,
            onPanResponderRelease: this.onPanResponderRelease,
        });
    }

    //========================API 呼叫順序 part 1========================
    onStartShouldSetPanResponderCapture = () => {
        window.console.log('debug keyword: onStartShouldSetPanResponderCapture === call order 1.');//首先呼叫此方法
        return false;
    };
    onStartShouldSetPanResponder = () => {
        window.console.log('debug keyword: onStartShouldSetPanResponder === call order 1.');//如果 onStartShouldSetPanResponderCapture 返回 true 則此方法不會被呼叫
        return true;
    };
    
    onMoveShouldSetPanResponderCapture = (evt, gestureState) => {//如果 onStartShouldSetPanResponderCapture 或者 onStartShouldSetPanResponder 返回 true 則此方法不會被呼叫
        window.console.log('debug keyword: onMoveShouldSetPanResponderCapture === call order 2.');
        return false;
    };
    onMoveShouldSetPanResponder = (evt, gestureState) => {//如果 onMoveShouldSetPanResponderCapture 或者 onStartShouldSetPanResponder 返回 true 則此方法不會被呼叫
        window.console.log('debug keyword: onMoveShouldSetPanResponder === call order 2.');
        return true;
    };

    //========================API 呼叫順序 part 2========================
    //onPanResponderGrant 方法和 onResponderReject 方法視情況而呼叫
    onPanResponderGrant = () => {
        window.console.log('debug keyword: onPanResponderGrant === call order 3.');
    };
    onResponderReject = () => {
        window.console.log('debug keyword: onResponderReject === call order 3.');
    };

    //========================API 呼叫順序 part 3========================
    //只有當 onStartShouldSetPanResponder 返回為 true 時,此方法被呼叫
    onPanResponderStart = () => {
        window.console.log('debug keyword: onPanResponderStart === call order 4.');
    };

    //========================API 呼叫順序 part 4========================
    //以下方法順序呼叫
    handlePanResponderMove = () => {
        window.console.log('debug keyword: handlePanResponderMove === call order 5.');
    };
    onPanResponderEnd = () => {
        window.console.log('debug keyword: onPanResponderEnd === call order 6.');
    };
    onPanResponderRelease = () => {
        window.console.log('debug keyword: onPanResponderRelease === call order 7.');
    };

    render() {
        return <View style={Styles.wrap} {...this._panResponder.panHandlers}/>;
    }
}

const Styles = StyleSheet.create({
    wrap: {
        flex: 1,
        width: SCREEN_WIDTH,
        height: SCREEN_HEIGHT,
        backgroundColor: '#feafea'
    }
});