如何捕获React Native组件之外的所有点击?

时间:2018-04-18 20:01:51

标签: javascript reactjs react-native

我试图找出如何捕获所有点击事件以确定它们是否在我的SearchBar下拉菜单之外被点击了。如果是,则下拉菜单将关闭。我有办法检测所有点击事件(TouchableWithoutFeedback),但我无法找到比较或确定它是否在我的组件之外的方法。任何人都知道如何在React Native ??

中做到这一点
class Products extends Component {

    constructor(props) {
        super(props);

        this.hideSearchBar = this.hideSearchBar.bind(this);
    }

    hideSearchBar(e) {
        console.log('e: ', e.nativeEvent.target)
        // Determine if the click event was outside of the SearchBar component
    }

    render() {
        const {isLoading, products} = this.props.products;

        return (
            <TouchableWithoutFeedback onPress={(e) => this.hideSearchBar(e)} style={{zIndex: 0}}>
                <View style={styles.wrapper}>
                    <Header/>
                    <View style={styles.bodyWrapper}>
                        <ScrollView style={styles.scrollView}>
                            <ProductsContainer data={{productsList: { results: products }}}/>
                        </ScrollView>
                        <SearchBar ref={node => this.node = node} style={styles.searchBar}/>
                    </View>
                    <Footer/>
                </View>
            </TouchableWithoutFeedback>
        );
    }
}

1 个答案:

答案 0 :(得分:2)

您可以根据PanResponder确认点击次数。

PanResponder包含提到的方法here

但你只需要

  • onMoveShouldSetPanResponderCapture:设置捕捉互动的动作。
  • onPanResponderMove:捕捉移动中的事件
  • onPanResponderTerminationRequest:如果其他资源需要访问响应者,则终止响应者。

这是简单示例

注意:您需要在父视图上设置PanResponder Handler以访问整个屏幕中的触摸事件。

const touchThreshold = 20;

state = {
        outsideTarget: null,
    }

componentWillMount () {
        this._panResponder = PanResponder.create({   //...Create the Responder
            // Ask to be the responder:
             // Ask to be the responder:
        onMoveShouldSetPanResponderCapture: (evt, gestureState) => {
            const {dx, dy} = gestureState;

            return (Math.abs(dx) > touchThreshold) || (Math.abs(dy) > touchThreshold);
        },
            onPanResponderMove: (evt, gestureState) => {
                console.log('Responder' + evt.nativeEvent.target)
                this.setState({outsideTarget: true})
                // The most recent move distance is gestureState.move{X,Y}

                // The accumulated gesture distance since becoming responder is
                // gestureState.d{x,y}
            },
            onPanResponderTerminationRequest: (evt, gestureState) => true,

        });
    }

componentDidUpdate(prevProps, prevState, snapshot) {
       if(this.state.outsideTarget) {
            Alert.alert('Success', 'Component Clicked OutSide')
        } else if(!this.state.outsideTarget) {
           Alert.alert('Success', 'Component Clicked Inside')

       }
    }


 hideSearchBar(e) {
    // Determine if the click event was outside of the SearchBar component
    this.setState({outsideTarget: false})
}

render() {
    return (
        <View style={{flex: 1}}  {...this._panResponder.panHandlers}> //...Set the responder to the parent view
            <TouchableOpacity  onPressIn={(e) => this.hideSearchBar(e)} style={{height: 100, width: 100, backgroundColor: 'red'}} />
        </View>
    );
}
  

如果响应者的本机事件目标可触摸的本机事件目标匹配,则内,否则之外