React Native:ScrollView中的TouchableOpacity onPress问题

use*_*841 12 android scrollview react-native

我正在运行反应本机0.24.1并且<TouchableOpacity>当它放在一个组件内时我遇到了组件的问题<ScrollView>.

它的onPress事件很好,但有一个特殊情况,他们没有.如果<TouchableOpacity>你有一个组件<TextInput>,并且当前焦点在<TextInput>盒子上,那么你可以点击它<TouchableOpacity>,你会看到它的onPress事件不会被触发.

至少你第一次这样做.一旦焦点<TextInput>不再存在,您现在可以按下该<TouchableOpacity>组件,其onPress事件将会正常启动.

请注意,如果<TouchableOpacity>组件放在一个<View>而不是<ScrollView>一切按预期工作,并且上述问题不适用.

以下是一些演示此问题的代码:

const React = require('react-native');
const {
  Component,
  Dimensions,
  View,
  ScrollView,
  Text,
  TextInput,
  TouchableOpacity,
} = React;


// ----------------------------------------------------------------------------
class TouchableOpacityTest extends Component {
  constructor(props, context) {
    super(props, context);
    this.state = {count_onPress:0,count_onPressIn:0,count_onPressOut:0,count_onLongPress:0};
  }
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  onPressEvent(what,e) {
    console.log('what:',what);
    let newState = {};
    newState['count_'+what] = ++this.state['count_'+what];
    this.setState(newState);
  }
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  render() {
    let touchableProps = {
      onPress: this.onPressEvent.bind(this,'onPress'),
      onPressIn: this.onPressEvent.bind(this,'onPressIn'),
      onPressOut: this.onPressEvent.bind(this,'onPressOut'),
      onLongPress: this.onPressEvent.bind(this,'onLongPress'),
    }

    return (
      <View style={{flex:1,flexDirection:'column',justifyContent:'flex-start',alignItems:'center',backgroundColor:'blue'}} >
        <ScrollView style={{width:Dimensions.get('window').width*0.9,backgroundColor:'red'}}>
          <TextInput style={{backgroundColor:'rgb(200,200,200)',marginTop:14}}
            placeholder="Focus on me,hide keyboard,and click on text below"
            autoCorrect={false}
          />
          <TouchableOpacity {...touchableProps} >
            <Text style={{fontSize:20,backgroundColor:'pink',marginTop:14}}>
              Click on me!{"\n"}
              onPress:{this.state.count_onPress}{"\n"}
              onPressIn:{this.state.count_onPressIn}{"\n"}
              onPressOut:{this.state.count_onPressOut}{"\n"}
              onLongPress:{this.state.count_onLongPress}{"\n"}
            </Text>
          </TouchableOpacity>
        </ScrollView>
      </View>
    );
  }
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}
// ----------------------------------------------------------------------------
AppRegistry.registerComponent('react_native_app1', () => TouchableOpacityTest);
Run Code Online (Sandbox Code Playgroud)

您可以<ScrollView>使用<View>上面代码中的组件替换它,您将看到onPress事件每次都会触发,即使焦点位于<TextView>

注意:我正在使用Android.我不知道这是否也发生在iOS上.

注2:根据Aakash Sigdel的说法,这确实也发生在iOS上.

Tim*_*ott 15

设置keyboardShouldPersistTaps={true}在你的ScrollView.

这里有重复的答案:https://stackoverflow.com/a/34290788/29493

更新:正如Hossein在他的回答中写道,true|false在新版本中已经弃用了赞成always|never|handled.


Hos*_*ein 5

设置keyboardShouldPersistTaps='always'你的ScrollView道具.

反应原生文档:

'never'(默认值),当键盘向上时,在聚焦文本输入外部轻敲键盘.发生这种情况时,孩子们不会收到水龙头.

'always',键盘不会自动消失,滚动视图不会捕捉到点击,但滚动视图的子节点可以捕捉到点击.

'处理',当孩子处理水龙头(或由祖先捕获)时,键盘不会自动解除.

false,弃用,使用'never'代替.

true,不赞成使用'always'代替.