RN TouchableOpacity点击事件不响应原因详解

问题

在这里插入图片描述

首先是整个页面布局如上:

在实际开发中发现 如下红框中的所有区域点击事件均没有效果,不会触发

image-20211217142319451

问题定位

RN基本触摸组件尝试

TouchableHighlight、TouchableNativeFeedback、 TouchableOpacity 、 TouchableWithoutFeedback

  • onPressIn:点击开始;
  • onPressOut:点击结束或者离开;
  • onPress:单击事件回调;
  • onLongPress:长按事件回调。

以上触摸事件无论怎么尝试在红框区域内都是无效事件

Pressable

Pressable 是一个核心组件的封装,它可以检测到任意子组件的不同阶段的按压交互情况

这个点击也是无效操作,到时官方文档里面的一句提示:触控区域不会超出绑定的父级 view,在按压到重叠的兄弟视图时,z-index 更高的那个视图会更优先

受到启发做一下尝试:

定位布局&解决方案

首先真机上打开Android调试工具的布局边框,展示如下前端的布局效果

9EF5FC4EBBF1C472D57144248DDDC89B
  • 首先是顶部带背景banner区域的

  • 然后是签到卡片

  • 从布局上可以明显看到banner和签到卡片是有区域交叉重叠的

  • 从代码定位来一步步排查

    const styles = StyleSheet.create({
      banner: {
            height: 170,
            width: width,
            paddingTop: 25,
            paddingLeft: 15,
            backgroundColor: Colors.F4F5F7,
        },
    })
    <ImageBackground
          style={styles.banner}
          source={imageBanner}
          resizeMode="contain"
      >
          <Text style={styles.bannerTitle}>当前可用积分</Text>
          <View style={styles.bannerLeft}>
              <Text style={styles.bannerLeftCount}>
                  {taskInfo?.totalPoints}
              </Text>
              <TouchableOpacity
                  onPress={() => {
                      jumpToNewTask();
                  }}
              >
                  <ImageBackground
                      style={styles.newTaskBtn}
                      source={NewTaskBtn}
                  >
                      <Image
                          style={styles.bannerLeftImage}
                          source={MoneyImage}
                      />
                      <Text style={styles.newTaskText}>新手任务</Text>
                      <Image
                          style={styles.triangle}
                          source={TriangleRight}
                      />
                  </ImageBackground>
              </TouchableOpacity>
          </View>
          <TouchableOpacity
              style={styles.redeemBtnContent}
              onPress={() => {
                  jumpToRedeem();
              }}
          >
              <ImageBackground
                  style={styles.redeemBtn}
                  source={RedeemBtn}
              >
                  <Text style={styles.redeemBtnText}>积分兑换</Text>
              </ImageBackground>
          </TouchableOpacity>
      		{/* 七天签到区域 */}
          <SignList
              data={taskDaily}
              info={taskInfo}
              signCallback={() => {
                  getTaskInfo();
                  getSignListInit();
              }}
          />
      </ImageBackground>
    
  • 从代码中可以明显看到签到卡片被包裹到banner的ImageBackground内部了 而banner的高度只有170px

  • 这样的话根据官方说的触控区域不会超过父级容器区域,那可实际可点击区域只有banner高度170内是可触控区域了
    image-20211218150116687

  • 那么到这问题就已经很清晰了 ,需要修改页面整体布局,具体如下

    const styles = StyleSheet.create({
      banner: {
            height: 170,
            width: width,
            paddingTop: 25,
            paddingLeft: 15,
            backgroundColor: Colors.F4F5F7,
        },
      signListContent: {
            borderRadius: 8,
            backgroundColor: Colors.FFFFFF,
            width: width - 30,
            marginTop: 25,
            paddingVertical: 20,
            position: 'absolute',
            top: 80,
            left: 15,
        }
    })
    <ImageBackground
          style={styles.banner}
          source={imageBanner}
          resizeMode="contain"
      >
          <Text style={styles.bannerTitle}>当前可用积分</Text>
          <View style={styles.bannerLeft}>
             ...
          </View>
          ...
      </ImageBackground>
      {/* 七天签到区域 */}
      <SignList
          data={taskDaily}
          info={taskInfo}
          signCallback={() => {
              getTaskInfo();
              getSignListInit();
          }}
      />
    
  • 签到卡片直接拿出来和banner平级,然后使用定位absolute来把卡片叠加到banner区域,这样他的父容器就是最外层的body文档流了,这样卡片内部都是可触控区域了,完美解决问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值