React Native - 如何捕获绝对位置组件后面的触摸事件

时间:2017-05-17 21:30:31

标签: javascript react-native react-native-flexbox

我正在尝试弹出一个对话框(创建为一个位置为'absolute'的组件),并在用户在弹出窗口外点击时关闭它。

我是React Native的新手,所以我做的其他事情可能是错的,原谅我:)

这是弹出窗口打开时的屏幕截图 enter image description here

这是一些代码:

来自Popup组件:

render() {
    if (!this.props.open) {
      return <View />
    }
    return (
      <View style={styles.container}>
        <View style={styles.popupStyle}>
            <View style={{flex:1, justifyContent: 'center', marginRight: 10}}>
                <View style={styles.amountEnterStyle}>
                  <TextInput
                    keyboardType={'numeric'}
                    underlineColorAndroid='transparent'
                    autoCorrect={false}
                    style={styles.textInputStyle}
                    value={this.state.amount}
                    onChangeText={this._onAmountEnter.bind(this)} />
                  <Text style={styles.currencyTextStyle}>NIS</Text>
                </View>
                <View style={styles.separatorStyle} />
                    <View style={styles.categorySectionStyle}>
                      {this._renderCategoryDropdown()}
                    </View>
              </View>
            <View style={{justifyContent: 'center'}}>
              <TouchableWithoutFeedback
                onPress={this._onAddPaymentClicked.bind(this)} >
                <View style={{width: 110, height:100, backgroundColor: "#ff0000"}} />
              </TouchableWithoutFeedback>
            </View>
        </View>
      </View>
    );

const styles = StyleSheet.create({
    container: {
      position: 'absolute',
      top: 0,
      bottom: 0,
      left: 0,
      right: 0,
      width: undefined,
      height: undefined,
      justifyContent: 'center',
      alignItems: 'center',
    },
    amountEnterStyle: {
      justifyContent: 'center',
      alignItems: 'center',
      flexDirection: 'row'
    },
    textInputStyle: {
      width: 100,
      fontSize: 50,
      fontWeight: 'bold',
      height: 65,
      flex: 1,
      marginTop: -20,
      paddingBottom: 0,
      marginBottom: 0,
      marginLeft:10,
      textAlignVertical: 'center'
    },
    currencyTextStyle: {
      fontSize: 50,
      color: '#c0c0c0',
      marginTop: -20,
      textAlignVertical: 'center'
    },
    separatorStyle: {
      height: 2,
      marginTop: 0,
      backgroundColor: '#c0c0c0',
    },
    categorySectionStyle: {
        justifyContent: 'flex-start',
        flexDirection: 'row',
        alignItems: 'flex-start',
        marginTop: 8
    },
    categoryColorDotStyle: {
      width: 20,
      height: 20,
      borderRadius: 100/2,
      marginLeft: 10,
      marginTop: 5,
    },
    categoryTextStyle: {
      fontSize: 24,
      marginHorizontal: 4,
      color: '#c0c0c0',
      marginLeft: 10,
      paddingRight: 10,
      marginTop: -3
    },
    popupStyle: {
      width: Dimensions.get('window').width - 60,
      flexDirection: 'row',
      justifyContent: 'space-between',
      height: 150,
      paddingRight:10,
      paddingLeft:10,
      borderRadius: 2,
      margin: 20,
      padding: 10,
      opacity: 1,
      borderRadius: 10,
      backgroundColor: '#ffffff'
   },
   dropdownSeparator: {
    height: 1,
    backgroundColor: 'cornflowerblue'
  },

这是托管组件:

render() {
    var totalIncome = this.props.balance.totalIncome;
    var totalExpanses = this.props.balance.totalExpanses;
    return (
      <View style={{flex:1, justifyContent: 'space-between'}}>
        <Image pointerEvents='none' source={require('../../res/background.png')} style={styles.container} />
        <MainScreenHeader onSettingPress={this._onBalanceSettingsPress.bind(this)}/>
        <MainBalanceCounter totalCount={totalIncome} currentCount={totalIncome-totalExpanses} />
        <View style={{justifyContent: 'center', alignItems: 'center', marginBottom: 150}}>
          <AddPaymentButton onPress={this._onAddPaymentPress.bind(this)} />
          <PaymentPopup
              open={this.state.paymentPopupOpen}
              onAddPaymentClicked={this._onPaymentPopupAddClicked.bind(this)} />
        </View>

      </View>
    );
  }


const styles = StyleSheet.create({
  container: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    width: undefined,
    height: undefined,
    backgroundColor:'transparent',
    justifyContent: 'center',
    alignItems: 'center',
  },
  innerContainer: {
    justifyContent: 'space-around',
    alignItems: 'center',
    flex: 1,
    backgroundColor: 'transparent'
  },
});

我正在尝试使用一个可以捕获弹出窗口外发生的点击的视图,但没有成功。

非常感谢任何帮助,

谢谢, Giora。

1 个答案:

答案 0 :(得分:0)

你试过react-native-modalbox吗?我在我的应用程序中使用它,它的工作非常好。如果您在模态后面有触摸事件,它将关闭。此外,您可以定义您希望模态的大小。它不必占用整个屏幕。

否则,你走在正确的轨道上。您需要一个涵盖屏幕整个宽度和高度的TouchableWithoutFeedback组件。您的弹出窗口将与此组件一起使用更高的zIndex。如果你想走这条路,请告诉我,我可以提供更多建议。干杯!