1import React, { Component } from 'react'; 2import { StyleSheet, View, StyleProp, ViewStyle } from 'react-native'; 3import { 4 LongPressGestureHandler, 5 State, 6 TapGestureHandler, 7 LongPressGestureHandlerStateChangeEvent, 8 TapGestureHandlerStateChangeEvent, 9} from 'react-native-gesture-handler'; 10 11interface FBState { 12 singleTap?: State; 13 longPress?: State; 14} 15 16export default class FancyButton extends Component< 17 { 18 style?: StyleProp<ViewStyle>; 19 onLongPress?: () => void; 20 onSingleTap?: () => void; 21 onDoubleTap?: () => void; 22 }, 23 FBState 24> { 25 doubleTapRef = React.createRef<TapGestureHandler>(); 26 27 readonly state: FBState = {}; 28 29 render() { 30 return ( 31 <LongPressGestureHandler minDurationMs={800} onHandlerStateChange={this._onLongPressEvent}> 32 <TapGestureHandler 33 numberOfTaps={1} 34 waitFor={this.doubleTapRef} 35 onHandlerStateChange={this._onSingleTapEvent}> 36 <TapGestureHandler 37 numberOfTaps={2} 38 ref={this.doubleTapRef} 39 onHandlerStateChange={this._onDoubleTapEvent}> 40 <View 41 style={[styles.button, this.props.style, { opacity: this._isPressed() ? 0.5 : 1 }]}> 42 {this.props.children} 43 </View> 44 </TapGestureHandler> 45 </TapGestureHandler> 46 </LongPressGestureHandler> 47 ); 48 } 49 50 _isPressed = () => { 51 const { longPress, singleTap } = this.state; 52 53 // Intentionally leave out double tap 54 if (longPress === State.BEGAN || singleTap === State.BEGAN) { 55 return true; 56 } else { 57 return false; 58 } 59 }; 60 61 _onLongPressEvent = (event: LongPressGestureHandlerStateChangeEvent) => { 62 const { state } = event.nativeEvent; 63 this.setState({ longPress: state }); 64 65 if (state === State.ACTIVE) { 66 this.props.onLongPress && this.props.onLongPress(); 67 } 68 }; 69 70 _onSingleTapEvent = (event: TapGestureHandlerStateChangeEvent) => { 71 const { state } = event.nativeEvent; 72 this.setState({ singleTap: state }); 73 74 if (state === State.ACTIVE) { 75 this.props.onSingleTap && this.props.onSingleTap(); 76 } 77 }; 78 79 _onDoubleTapEvent = (event: TapGestureHandlerStateChangeEvent) => { 80 const { state } = event.nativeEvent; 81 82 if (state === State.ACTIVE) { 83 this.props.onDoubleTap && this.props.onDoubleTap(); 84 } 85 }; 86} 87 88const styles = StyleSheet.create({ 89 button: { 90 paddingHorizontal: 30, 91 paddingVertical: 20, 92 backgroundColor: '#cacaca', 93 borderRadius: 5, 94 alignItems: 'center', 95 }, 96}); 97