事件分发机制:demo复现自定义ViewGroup点击事件不起作用

几年前遇到的一个bug,不弄清楚心里就是不舒服!

平时应用开发中,经常遇到的UI需求,例如抖音的设置界面,如下图所示:

很容易想到,自定义一个Layout,左边一个图标,中间文字说明,右侧一个箭头,底部一条分割线。点击整个条目,跳转到另外一个Activity。动手写的时候,就遇到bug了,item的点击事件不起作用。

看bug情况,如下图:

点击子View有效果,点击自定义的布局没有log。这是怎么回事?

看看代码:

public class RelativeActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_relative);}
}//activity布局:
<?xml version="1.0" encoding="utf-8"?>
<com.exp.clickdemo.rl_bug.MyRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"></com.exp.clickdemo.rl_bug.MyRelativeLayout>

自定义的布局MyRelativeLayout:

public class MyRelativeLayout extends RelativeLayout {public MyRelativeLayout(Context context) {this(context,null);}public MyRelativeLayout(Context context, @Nullable AttributeSet attrs) {this(context, attrs,0);}public MyRelativeLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);LayoutInflater inflater = (LayoutInflater)   getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);inflater.inflate(R.layout.my_relativelayout, this);setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Log.i("xx", "click MyRelativeLayout");}});ImageView iv = findViewById(R.id.iv);iv.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Log.i("xx", "click ImageView");}});}
}

item布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="80dp"android:clickable="true"android:background="#00ff00"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerVertical="true"android:text="通用设置"android:textSize="28sp" /><ImageViewandroid:id="@+id/iv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:layout_centerVertical="true"android:src="@drawable/icon_goto" /></RelativeLayout>

按道理讲,点击箭头左侧区域,应该有日志“click MyRelativeLayout" 才对。为什么没有了?

在设置点击事件的后面加一行代码:

Log.i("xx", "MyRelativeLayout is clickable:" + isClickable());

日志显示:I/xx: MyRelativeLayout is clickable:true,也就是说MyRelativeLayout可以点击,可以点击,又有点击事件,为啥就不起作用了?

继续尝试,把item布局中android:clickable="true"去掉,神奇的是,点击事件竟然起作用了,这里就不贴日志和效果了。不卖关子了,直接说原因:设置android:clickable="true"后,布局中的RelativeLayout消费了点击事件,但是这个RelativeLayout又没有onClickListener,所以没有日志。外层的MyRelativeLayout虽然可以点击,也设置了点击事件,但是点击事件已经被RelativeLayout消费了。把android:clickable="true"去掉后,RelativeLayout不可点击,消费事件回传给MyRelativeLayout,这样点击事件又起作用了。

为了验证上面的分析,我们把android:clickable="true"再加回去,在Activity的布局中,给MyRelativeLayout加上红色背景,再设置padding:

    android:padding="20dp"android:background="#ff0000"

点击看看效果:

可以看出MyRelativeLayout的点击事件是起作用的,只不过没有回传给它,就已经消费调了。而消费点击事件的RelativeLayout,又没有设置onClickListener,所以点击就没有日志。

代码已经上传到Gitee上,地址是:https://gitee.com/zhagnjinaaaa/click-demo,后面的博客,会继续跟踪代码,深挖原因!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1473282.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

二维树状数组区域查询

落谷4514 过关代码如下 #define _CRT_SECURE_NO_WARNINGS #include<bits/stdc.h> using namespace std; //#define int long longconst int N 2050; int t1[N][N], t2[N][N], t3[N][N], t4[N][N]; int lowbit(int x) { return x & (-x); } int n, m; void update(…

@Slf4j idea标红Cannot resolve symbol ‘log‘

一、背景 时间久了没有应用idea,打开工程后项目 log 提示报红&#xff0c;未能解析&#xff0c;Cannot resolve symbol log &#xff0c;Slf4j 注解正常&#xff0c;应用的lombok插件。 检查lombok插件安装情况&#xff0c;发现未安装&#xff0c;重新安装重启idea后正常。 二…

zxing-cpp+OpenCV根据字符串生成条形码

编译构建 需要使用到 CMake、Git、GCC 或 MSVC。 github 链接&#xff1a;https://github.com/zxing-cpp/zxing-cpp 编译之前请确保&#xff1a; 确保安装了 CMake 版本 3.15 或更高版本。 确保安装了与 C17 兼容的编译器(最低VS 2019 16.8 / gcc 7 / clang 5)。 编译构建…

什么是 VueQuill(前端的富文本编辑器)?

什么是 VueQuill&#xff1f; 1. 简介 VueQuill 是 Vue.js 的一个富文本编辑器插件&#xff0c;它基于 Quill 编辑器构建&#xff0c;提供了简洁且功能强大的富文本编辑功能。Quill 是一个现代化的富文本编辑器&#xff0c;提供丰富的文本编辑能力&#xff0c;支持多种格式和…

Beats:使用 Filebeat 从 Python 应用程序中提取日志

本指南演示了如何从 Python 应用程序中提取日志并将其安全地传送到 Elasticsearch Service 部署中。你将设置 Filebeat 来监控具有标准 Elastic Common Schema (ECS) 格式字段的 JSON 结构日志文件&#xff0c;然后你将在 Kibana 中查看日志事件发生的实时可视化。虽然此示例使…

前缀和数组 差分数组

前缀和 一维&#xff1a;通过空间换时间适用于需要频繁查询某一段区间和的场景。 一维数组&#xff1a; 一维前缀和中的每一项&#xff1a; &#xff0c;该前缀和中的每一项也就是数组中对应的前 i 项和。 一维前缀和数组的构造&#xff1a; 在输入原数组时同步构造前缀和…

2024年中国陶瓷轴承用氮化硅粉体市场发展现状及重点竞争企业研究

2024年中国陶瓷轴承用氮化硅粉体市场发展现状及重点竞争企业研究 氮化硅是一种硬度高、结构稳定、热膨胀系数小&#xff0c;抗氧化和抗侵蚀性能好的一种的陶瓷材料&#xff0c;可用于制造高性能氮化硅陶瓷结构件、坩埚涂层等。近年来&#xff0c;伴随着机械制造行业进一步向高精…

WPF UI 3D 基本概念 点线三角面 相机对象 材质对象与贴图 3D地球 光源 变形处理 动作交互 辅助交互插件 系列三

WPF UI交互专题 平面图形 Path Drawing 绘图 渐变 Brush 矩阵 Transform 变形 阴影效果 模糊效果 自定义灰度去色效果 系列二-CSDN博客 1软件中的3D基本概念 WPF 中 3D 功能的设计初衷并非提供功能齐全的游戏开发平台。 WPF 中的 3D 图形内容封装在 Viewport3D 元素中&#x…

期末上分站——计组(2)

复习题11-20 11、 某DRAM芯片&#xff0c;其存储容量为512K8位&#xff0c;该芯片的地址线和数据线的数目是_D__。 A. 8, 512 B. 512, 8 C. 18, 8 D. 19 ,8 解析: 某DRAM芯片&#xff0c;其存储容量为512K8位时&#xff0c;该芯片的地址线和数据线的数目是D选项&a…

【吊打面试官系列-MyBatis面试题】为什么说 Mybatis 是半自动 ORM 映射工具?它与全自动的区别在哪里?

大家好&#xff0c;我是锋哥。今天分享关于 【为什么说 Mybatis 是半自动 ORM 映射工具&#xff1f;它与全自动的区别在哪里&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; 为什么说 Mybatis 是半自动 ORM 映射工具&#xff1f;它与全自动的区别在哪里&#xf…

LabVIEW与OpenCV图像处理对比

LabVIEW和OpenCV在图像处理方面各有特点。LabVIEW擅长图形化编程、实时处理和硬件集成&#xff0c;而OpenCV则提供丰富的算法和多语言支持。通过DLL、Python节点等方式&#xff0c;OpenCV的功能可在LabVIEW中实现。本文将结合具体案例详细分析两者的特点及实现方法。 LabVIEW与…

JAVA学习笔记-JAVA基础语法-DAY21-缓冲流、转换流、序列化流

第一章 缓冲流 昨天学习了基本的一些流&#xff0c;作为IO流的入门&#xff0c;今天我们要见识一些更强大的流。比如能够高效读写的缓冲流&#xff0c;能够转换编码的转换流&#xff0c;能够持久化存储对象的序列化流等等。这些功能更为强大的流&#xff0c;都是在基本的流对象…

45 mysql truncate 的实现

前言 truncate 是一个我们也经常会使用到的命令 其作用类似于 delete from $table; 但是 他会比 delete 块很多&#xff0c;这里我们来看一下 它的实现 delete 的时候会逐行进行处理, 打上 删除标记, 然后 由后台任务 进行数据处理 truncate table 的实现 执行 sql 如下 …

C++20中的基于范围的for循环(range-based for loop)

C11中引入了对基于范围的for循环(range-based for loop)的支持&#xff1a;该循环对一系列值(例如容器中的所有元素)进行操作。代码段如下&#xff1a; const std::vector<int> vec{ 1,2,3,4,5 }; for (const auto& i : vec)std::cout << i << ", …

OpenCV从图像中截取矩形区域

使用OpenCV可以很容易地实现将一个图像文件内部指定矩形范围内的图像复制为新的图像。 import cv2# 读取原始图像 image cv2.imread(mm.png) cv2.imshow(Origi Image, image)# 定义矩形框的坐标 x, y, width, height 20, 30, 200, 300 # 坐标和尺寸# 截取矩形框内的图像 cr…

CTF入门知识点

CTF知识点 md5函数 <?php$a 123;echo md5($a,true); ?> 括号中true显示输出二进制 替换成false显示输出十六进制绕过 ffifdyop 这个字符串被 md5 哈希了之后会变成 276f722736c95d99e921722cf9ed621c&#xff0c;这个字符串前几位刚好是 or 6 而 Mysql 刚好又会把 …

Hasleo Backup Suite 一款专为Windows操作系统设计的免费数据备份与恢复软件,支持备份、恢复和克隆功能

数据安全是每位计算机用户都关心的重要问题。在日常使用中&#xff0c;我们经常面临文件丢失、系统崩溃或病毒感染等风险。为了解决这些问题&#xff0c;我们需要可靠且高效的数据备份与恢复工具。本文将介绍一款优秀的备份软件&#xff1a;Hasleo Backup Suite&#xff0c;它为…

win11中配制了系统的环境变量mvn/java,但是mvn/java就是提示不存在的解决方法。

1、已经配制了环境变量&#xff0c;但是提示mvn不存在 2、然后我们在开始程序中查看到cmd&#xff0c;然后以管理员运行&#xff1a; 这样的话&#xff0c;是可以mvn这个命令的&#xff0c;而且只有这种方式是可以的&#xff0c;其它的方式&#xff0c;就算设置了以管理员身份运…

图像分类-数据驱动方法

K近邻算法&#xff08;K-Nearest Neighbors&#xff0c;简称KNN&#xff09; KNN算法通过比较新样本与训练集中的样本的距离&#xff0c;然后根据最近的K个邻居的投票结果来决定新样本的分类。 如图所示&#xff0c;K越大的边界会更加平滑&#xff0c;本质上是根据某一样本最近…

沉浸式三维园区场景漫游体验

利用图扑三维可视化技术展示园区在不同时间段的变化&#xff0c;提供全景漫游体验&#xff0c;帮助用户全方位感受和理解园区环境&#xff0c;实现智能化管理与优化。