基本上,我希望将单个OnClickListener附加到ConstraintLayout中的多个视图。
在迁移到ConstraintLayout之前,视图位于一个布局内,我可以在其中添加侦听器。现在,它们与ConstraintLayout下的其他视图位于同一层。
我尝试将视图添加到android.support.constraint.Group
,并以编程方式向其中添加了OnClickListener。
group.setOnClickListener {
Log.d("OnClick", "groupClickListener triggered")
}
但是,对于ConstraintLayout版本1.1.0-beta2
,这似乎不起作用
我是否做错了什么,是否有办法实现这种行为,或者我是否需要将侦听器附加到每个单一视图?
8条答案
按热度按时间rseugnpd1#
从多个视图监听单击事件的更好方法是在所有需要的视图上添加一个透明视图作为容器。这个视图必须在所有需要执行单击的视图的末尾(即顶部)。
示例容器视图:
上面的示例包含了所有四个约束边界,我们可以添加要一起侦听的视图,因为它是一个视图,所以我们可以做任何我们想要的事情,比如涟漪效应。
ecfdbz9o2#
为了补充Kotlin用户接受的答案,创建一个扩展函数,并接受一个lambda,使其更像API
group.addOnClickListener { }
。创建扩展函数:
用法:
col17t5w3#
扩展方法很棒,但您可以通过将其更改为
所以召唤应该是这样的
现在不再需要显式定义View.OnClickListener了。
您还可以为GroupOnClickLitener定义自己的接口,如下所示
然后定义如下扩展方法
像这样使用
第二种方法在视图数量很大的情况下性能更好,因为您只使用一个对象作为所有视图的侦听器!
qnyhuwrf4#
虽然我喜欢Vitthalk's answer中的一般方法,但我认为它有一个主要缺点和两个次要缺点。
1.它不考虑单个视图的动态位置变化
1.它可能会注册不属于组的视图的点击
1.它不是这个相当常见问题的通用解决方案
虽然我不确定第二点的解决方案,但第一点和第三点显然很容易解决。
1.要素在集团内核算位置变动
这其实很简单。可以使用约束布局的工具集来调整透明视图的边缘。我们只需使用Barriers来接收组中任何视图的最左、最右等位置。然后我们可以将透明视图调整到障碍物而不是具体视图。
3.通用解决方案
使用Kotlin,我们可以扩展Group-Class,使其包含一个如上所述的将ClickListener添加到View上的方法。该方法只是将Barriers添加到布局中,注意组的每个子组,与Barriers对齐的透明视图,并将ClickListener注册到后者。
这样,我们只需调用Group上的方法,而无需每次需要此行为时都手动将视图添加到布局中。
w6mmgewl5#
对于像我这样的Java用户:
我不喜欢这不是传播点击状态到所有其他的孩子。
ev7lccsx6#
在Constraintlayout 2.0.0中,您可以使用Layer来解决多视图单击事件,并且还支持缩放动画
l5tcr1uw7#
有趣约束布局。setAllOnClickListener(侦听器:(查看)-〉单元){子项.forEach {查看-〉根查看.findViewById(view.id).setOnClickListener {监听器.调用(此)} }}
然后.setAllOnClickListener {执行某些操作}
nsc4cvqm8#
ConstraintLayout
中的Group
只是视图AFAIK的一个松散关联,它不是ViewGroup
,因此您不能像在ViewGroup
中那样使用单击监听器。作为一种替代方法,您可以在代码中获取一个属于
Group
成员的id列表,并显式设置click侦听器。(我还没有找到关于此特性的官方文档,但我相信它只是滞后于代码发布。)请在此处查看有关getReferencedIds
的文档。java 语:
在Kotlin中,您可以为此构建一个扩展函数。
Kotlin:
然后对组调用函数:
更新
引用的id在 2.0.0-beta2 中并不是立即可用的,尽管它们在 2.0.0-beta1 和之前的版本中是可用的。“发布”上面的代码以在布局后获取引用id。类似的操作将起作用。
这应该适用于 2.0.0-beta2 之前的版本,因此您可以只执行此操作,而不必执行任何版本检查。