React Native:ScrollView 内的 TouchableOpacity onPress 问题

问题描述 投票:0回答:4

我正在运行 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);

您可以将上面代码中的

<ScrollView>
替换为
<View>
组件,您将看到 onPress 事件每次都会触发,即使焦点位于
<TextView>

注意:我正在Android上工作。我不知道 iOS 上是否也会发生这种情况。

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

android scrollview react-native
4个回答
21
投票

keyboardShouldPersistTaps={true}
设置在您的
ScrollView
上。

此处重复答案:https://stackoverflow.com/a/34290788/29493

更新: 正如侯赛因在他的回答中所写,

true|false
在新版本中已被弃用,取而代之的是
always|never|handled


11
投票

keyboardShouldPersistTaps='always'
设置为您的
ScrollView
道具。

React Native 文档:

'从不'(默认),当键盘抬起时点击焦点文本输入的外部会关闭键盘。发生这种情况时,孩子们将无法接受水龙头。

'always',键盘不会自动关闭,滚动视图不会捕获点击,但滚动视图的子级可以捕获点击。

'handled',当点击由孩子处理(或由祖先捕获)时,键盘不会自动关闭。

false,已弃用,请使用“从不”代替。

true,已弃用,请使用“始终”代替。


0
投票

就我而言,我正在使用 alignItems:'baseline', 当我切换到 alignItems:'center' 时,它开始顺利工作。不知道为什么


0
投票

就我而言,

onPress
根本没有发射。我通过将回调包装在
useCallback
中解决了这个问题。

我只在真实设备中遇到这个问题,这在 Android 模拟器中没问题。

© www.soinside.com 2019 - 2024. All rights reserved.