【问题标题】:React native TouchableOpacity onPress not working on Android反应本机 TouchableOpacity onPress 在 Android 上不起作用
【发布时间】:2019-05-02 01:37:29
【问题描述】:

TouchabelOpacity 在 iOS 上运行良好,但我的 onPress 方法在 Android 上不起作用。

我的 react-native 版本:0.57.4

我的代码:

const initDrawer = navigation => (
  <TouchableOpacity
    style={{ left: 16 }}
    onPress={() => onPressDrawerButton(navigation)}
  >
    <Ionicons name="ios-menu" color="white" size={30} />
  </TouchableOpacity>
);

【问题讨论】:

  • 我可以确认它在 0.57.7 版本的 Android 上运行良好。你能负担得起升级吗?

标签: android react-native touchableopacity touchablehighlight


【解决方案1】:

我有类似的问题。注意从哪里导入您的“TouchableOpacity”。当我将“TouchableOpacity”从“react-native-gesture-handler”更改为“react-native”时,它对我有用(适用于 Android 平台)

【讨论】:

  • 应该是答案
  • 这是实际有效的答案
  • 我建议添加一个禁止从 react-native-gesture-handler 导入的 eslint no-restricted-imports 规则。 'no-restricted-imports': [ 'error', { paths: [ { name: 'react-native-gesture-handler', importNames: ['TouchableOpacity'], message: 'Import TouchableOpacity from react-native instead', }, ], }, ],
  • 对我来说,当我从 react-native 切换到 react-native-gesture-handler 时它起作用了
  • 这个自动导入的 rn 手势处理程序太烦人了
【解决方案2】:

我遇到了同样的问题,所有 TouchableOpacity 按钮在 iOS 版本中都可以正常工作,但在 Android 中有一个按钮没有触发。 我偶然发现了这个answer here 提到position: absolute 会弄乱触发器。它解决了我的问题。

【讨论】:

  • 我以类似的方式解决了我的问题。在层次结构方面,我有一个可触摸不透明度内的视图;我正在向视图添加定位,同时假设 Touchable Opacity 也会采用其子定位,这就是我的问题所在,点击视图不会执行我的方法,因为 touchable opacity 的定位与其子定位不同。我通过在 Touchable Opacity 而不是 View 上进行定位来解决它。希望这对某人有所帮助。
  • 这也是我的问题。绝对位置阻止 onPress 函数触发。谢谢亲的帮助。
  • 这对我有用,非常感谢!
【解决方案3】:

终止 Metro 服务器(以防它当前正在运行)然后再次运行它(如下所示)对我有用。


在运行 Metro 服务器的控制台上,终止

ctrl + c

然后在另一个控制台上,运行您的应用

react-native run-android

npx react-native run-android

【讨论】:

    【解决方案4】:

    对我来说,它可以工作,但可触摸区域非常小。不知何故,iOS 的面积比 Android 大。

    我最终使用hitSlop 属性增加了可触摸区域,如下所示:

    <TouchableOpacity
        onPress={() => {}}
        hitSlop={{ top: 30, bottom: 30, left: 30, right: 30 }}
    >
        <Icon name="eye" />
    </TouchableOpacity>
    

    【讨论】:

    • 每个人似乎都很快切换导入而不问为什么要修复它。就我而言,我不得不使用原生版本,因为 react-native-gesture-handler 版本不喜欢动画。 Mateo 的回答对我来说是正确的方法,因为 Android 上的命中区域为零,而在 iOS 上它采用了其子代的大小。在我的例子中,内容是一个固定的高度,所以我可以设置 TouchableOpacity 的高度来匹配它。
    【解决方案5】:

    检查您要从中导入可触摸不透明度的库。从“react-native”导入它。不是来自“react-native-gesture-handler”

    使用这个

    import { TouchableOpacity } from 'react-native';
    

    而不是这个

    import { TouchableOpacity } from 'react-native-gesture-handler';
    

    【讨论】:

      【解决方案6】:

      在我的例子中,我从“react-native-gesture-handler”导入了 TouchableOpacity 在我从“react-native”添加它之后,它起作用了

      【讨论】:

      • 是的,这可以使用,但是为什么从 react-native 导入它时不起作用??
      【解决方案7】:

      检查长按 Touchable 是否有效。在我的情况下,我在 Android 手机上进行测试,渲染多个 TouchableOpacity 会减慢手机速度,如果我太短暂地触摸该组件,它就不会注册为有效的按下。

      根据onPress上的官方文档,会取消无效按下: https://reactnative.dev/docs/touchablewithoutfeedback#onpress

      在这种情况下,您可以使用onPressOutonPressIn 而不是onPress 来确保您的触摸始终有效。

      【讨论】:

      • 非常感谢,这对我有用,我快要疯了:)
      • 我只在三星 S 系列设备上遇到过类似问题。我的 TochableOpacity 工作不稳定,几个月来一直在努力寻找解决方案。这解决了它。谢谢
      【解决方案8】:

      遇到了同样的问题。检查您的设备时间是否与它连接的机器时间相同。在我的情况下,这是 1 分钟的差异,这导致每个 TouchableOpacity 都不起作用。

      【讨论】:

        【解决方案9】:

        在某些情况下,原生调试器在 iOS 和 Android 平台上无法正常工作,我发现 TouchableOpacity 在启用调试器的 Android 上存在触摸错误。尝试禁用它,它会在构建后正常工作!

        【讨论】:

        • 这正是我发现的!多么奇怪。你找到导致这个问题的原因了吗?
        • @JaapWeijland 我想我找到了一些关于它的东西,但我还没有时间测试它。看看:github.com/facebook/react-native/issues/…
        • 我也发现了。在我看来,这确实是造成这种情况的原因。
        【解决方案10】:

        对我来说,我使用的是 NativeBase,并且具有以下结构,这在 Android 上是有问题的:

        <List>
            <TouchableOpacity>
               <ListItem>
                  <Text>Button</Text>
               </ListItem>
            </TouchableOpacity>
        </List>
        

        一旦我删除了ListItem 并将文本设为TouchableOpacity 的直接子代,然后它就起作用了。

        【讨论】:

          【解决方案11】:

          将图标包装在这样的视图中。

          const initDrawer = navigation => (
            <TouchableOpacity
              style={{ left: 16 }}
              onPress={() => onPressDrawerButton(navigation)}
            >
              <View style={{padding:5}}>
                  <Ionicons name="ios-menu" color="white" size={30} />
              </View>
            </TouchableOpacity>
          );
          

          如果问题仍然存在,请使用 backgroundColor 设置图标的样式,您会看到一半的图标没有使用 backgroundColor 设置样式,因此您必须提供更大的填充量。我不知道,但图标在体积方面往往存在问题,尤其是在 TouchableOpacity 中。 这就是为什么我自己制作一个带有图标填充的父视图。 其他人也提到的其他东西是 postion:'absolute' 道具,它与组件卷混淆。

          【讨论】:

            【解决方案12】:

            我忘记遵循 react-native-gesture-handler 的 Android 入门步骤:

            https://docs.swmansion.com/react-native-gesture-handler/docs/#android

            【讨论】:

              【解决方案13】:

              对我来说,从所有父项中删除“flex:1”。

              【讨论】:

              • 这对我也有用,但无法在零食中重现错误,或了解导致错误的原因。可以避免使用 flex,但不是理想的。有谁明白为什么父级(有时链上的几个节点)中的 flex: 1 属性可能会禁用子元素的任何 onPress 事件?
              【解决方案14】:

              TouchableOpacity 默认从“react-native-gesture-handler”包自动导入。此版本无法在安卓上正常运行。

              【讨论】:

              • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
              【解决方案15】:

              这里没有列出我的问题,所以想添加它。

              在 Android 上,如果您在 KeyboardAvoidingView 中有 TouchableOpacity,它将无法工作(至少在我使用的设置下)。

              只要我将 KeyboardAvoidingView 的范围限定为仅围绕输入字段而不是我的 TouchableOpacities,它就会再次开始工作。

              (顺便说一句,在IOS上很好)

              【讨论】:

                【解决方案16】:

                有同样的问题 - 在我的例子中,它是一个在 TouchableOpacity 内渲染的元素,带有 position: 'absolute' 并与 TouchableOpacity 成比例,我已将 zIndex: 0 添加到此元素使其工作。

                【讨论】:

                  【解决方案17】:
                  
                  <TouchableOpacity
                         style={{backgroundColor: 'red', width: 50, height: 50, zIndex: 1}}
                         onPress={() => alert('working')}>
                         <Text>tset</Text>
                   </TouchableOpacity>
                  

                  zIndex:1 像魔术一样工作。

                  【讨论】:

                    【解决方案18】:

                    如果您使用的是绝对位置。使用 zIndex 为 TouchableOpacity 注册点击

                    touchableOpacity: {
                    alignItems: 'center',
                    justifyContent: 'center',
                    width: 30,
                    height: 25,
                    zIndex: 1,
                    position: 'absolute',
                    left: 5},
                    

                    【讨论】:

                    • 绝对位置和 zIndex 50 在我的情况下修复
                    【解决方案19】:

                    对我来说,问题是媒体没有在TouchableWithoutFeedBack 上注册 Android。从react-native-gesture-handlerreact-native 导入没有任何区别。

                    为了解决这个问题,我从'react-native' 导入了TouchableOpacity,并将其与activeOpacity={1} 一起使用,以防止按下时更改不透明度。这给了我TouchableWithoutFeedback 的行为,但它适用于Android。

                    其实我把它改成了Pressable,它也可以工作

                    【讨论】:

                      【解决方案20】:

                      虽然以下问题是由最近发布的 React Native 引起的,但我认为这可能是最近遇到此问题的人的解决方案。

                      这可能是由于使用调试模式时设备上的时间与开发机器上的时间不匹配造成的。我通过关闭和打开设备的自动时间设置来解决此问题,这会“重新获取”时间,使其与我的开发机器同步。

                      此问题与此相关:

                      https://github.com/facebook/react-native/issues/27008

                      【讨论】:

                        【解决方案21】:

                        如果这对任何人有帮助,

                        旧代码

                        <TouchableOpacity onPress={()=>{callback()}} >
                           <View style={styles.action}>
                              <MaterialCommunityIcons name="close-thick" size={25} color={colors.white} style={styles.icon}/>
                           </View>
                        </TouchableOpacity>
                        

                        修复

                        <TouchableOpacity onPress={()=>{callback()}} style={styles.action}>
                           <View style={{flex:1}}>
                              <MaterialCommunityIcons name="close-thick" size={25} color={colors.white} style={styles.icon}/>
                           </View>
                        </TouchableOpacity>
                        

                        在我的 android 案例中,TouchableOpacity 从内部的视图(具有绝对位置)中呈现出来(这是预期的,因为位置不是绝对的)。将borderWidth 和borderColor 添加到TouchableOpacity 表明它已远离视图呈现。将样式从子视图切换到 TouchableOpacity 解决了这个问题。

                        【讨论】:

                          【解决方案22】:

                          我尝试了所有其他答案,但无法正常工作。就我而言,我有一个具有以下样式的父容器:

                          .parentContainer {
                              height: '100%',
                              width: '100%',
                              position: 'absolute',
                              top: '-20%'
                          }
                          

                          我意识到子容器溢出了父容器,虽然这在样式方面不是一个大问题,但所有溢出父容器的 TouchableOpacity 组件都不起作用(onPress 事件没有触发)。基本上任何位于屏幕底部 20% 的 TouchableOpacity 组件都不起作用,因为父级已向上移动 20%(顶部:'-20%')。我所要做的就是将父容器的高度从 100% 更改为 120%,然后它开始按预期工作。

                          【讨论】:

                            【解决方案23】:

                            尝试使用 onPressIn 代替 onPress。为我工作

                            【讨论】:

                              【解决方案24】:

                              对我来说,即使我从 react-native 导入 TouchableOpacity,上述答案都不起作用,所以我不得不再次检查 我的视图层次结构,然后再次,我意识到 我将包含 TouchableOpacity(s) 的视图放置在另一个应该是同级视图的视图中(作为其子视图)。因此,即使包含我的 touchableOpacity(ies) 及其子项的视图由于我分配给它的高度而在我的应用程序上可见,但其中的一些 touchableOpacities 没有响应触摸。

                              让我在这里尝试使用代码来举例说明(我假设您已经可以创建一个功能组件和一个导航堆栈,所以我将从组件内部的视图开始),请注意高度和层次:

                              <View style={{height:200, width:'100%', backgroundColor: 'blue'}}>
                               <View style={{height:400, width:'90%', backgroundColor: 'gray'}}>
                                <TouchableOpacity 
                                 onPress={()=>navigation.navigate("DifferentPage")}
                                 style={{height:100, width: '90%' }}>
                                  <Text> Please click me1 </Text>
                                </TouchableOpacity>
                              
                                <TouchableOpacity 
                                 onPress={()=>navigation.navigate("DifferentPage")}
                                 style={{height:100, width: '90%' }}>
                                  <Text> Please click me2 </Text>
                                </TouchableOpacity>
                              
                                <TouchableOpacity 
                                 onPress={()=>navigation.navigate("DifferentPage")}
                                 style={{height:100, width: '90%' }}>
                                  <Text> Please click me3 </Text>
                                </TouchableOpacity>
                              
                                <TouchableOpacity 
                                 onPress={()=>navigation.navigate("DifferentPage")}
                                 style={{height:100, width: '90%' }}>
                                  <Text> Please click me4 </Text>
                                </TouchableOpacity>
                              
                               <View>
                              
                              </View>
                              

                              现在有了上述结构,所有四个 TO 都将在我的应用程序中可见,但第一个和第二个肯定会起作用,但是当我点击第四个或什至第三个 TouchableOpacity 时,什么都不会发生。这是因为父视图的高度小于包含 TO 的子视图,并且 TO 的总高度超过了祖父视图的高度。

                              为了解决这个问题, 解决方案1:我可以简单地将父视图的高度增加到==400或>。 解决方案2:(我使用的):删除子视图并使其成为当前父视图的兄弟。如果您希望它们重叠,则可以在样式中使用定位。

                              【讨论】:

                                猜你喜欢
                                • 2018-06-22
                                • 1970-01-01
                                • 2019-03-20
                                • 2020-12-06
                                • 1970-01-01
                                • 2020-09-19
                                • 1970-01-01
                                • 1970-01-01
                                • 2017-08-30
                                相关资源
                                最近更新 更多