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 > 37 <TapGestureHandler 38 numberOfTaps={2} 39 ref={this.doubleTapRef} 40 onHandlerStateChange={this._onDoubleTapEvent} 41 > 42 <View style={[styles.button, this.props.style, { opacity: this._isPressed() ? 0.5 : 1 }]}> 43 {this.props.children} 44 </View> 45 </TapGestureHandler> 46 </TapGestureHandler> 47 </LongPressGestureHandler> 48 ); 49 } 50 51 _isPressed = () => { 52 const { longPress, singleTap } = this.state; 53 54 // Intentionally leave out double tap 55 if (longPress === State.BEGAN || singleTap === State.BEGAN) { 56 return true; 57 } else { 58 return false; 59 } 60 } 61 62 _onLongPressEvent = (event: LongPressGestureHandlerStateChangeEvent) => { 63 const { state } = event.nativeEvent; 64 this.setState({ longPress: state }); 65 66 if (state === State.ACTIVE) { 67 this.props.onLongPress && this.props.onLongPress(); 68 } 69 } 70 71 _onSingleTapEvent = (event: TapGestureHandlerStateChangeEvent) => { 72 const { state } = event.nativeEvent; 73 this.setState({ singleTap: state }); 74 75 if (state === State.ACTIVE) { 76 this.props.onSingleTap && this.props.onSingleTap(); 77 } 78 } 79 80 _onDoubleTapEvent = (event: TapGestureHandlerStateChangeEvent) => { 81 const { state } = event.nativeEvent; 82 83 if (state === State.ACTIVE) { 84 this.props.onDoubleTap && this.props.onDoubleTap(); 85 } 86 } 87} 88 89const styles = StyleSheet.create({ 90 button: { 91 paddingHorizontal: 30, 92 paddingVertical: 20, 93 backgroundColor: '#cacaca', 94 borderRadius: 5, 95 alignItems: 'center', 96 }, 97}); 98