如何在Android上将视图的onClick事件传递给其父级?


100

我在布局中有一个TextView,谁的背景是一个选择器。然后,将TextView的文本设置为“从HTML跨接”。然后,我使用LinkMovementMethod设置TextView。

现在,当我点击TextView时,click事件不会发送到其父布局以触发选择器。

应该如何解决?

Answers:


45

我认为您需要使用这些方法之一,以便能够在事件发送到适当的组件之前对其进行拦截:

Activity.dispatchTouchEvent(MotionEvent) -这使您的活动可以在所有触摸事件被分派到窗口之前拦截它们。

ViewGroup.onInterceptTouchEvent(MotionEvent) -这允许ViewGroup在将事件调度到子View时监视它们。

ViewParent.requestDisallowInterceptTouchEvent(boolean) -在父视图上调用此方法,以指示它不应使用onInterceptTouchEvent(MotionEvent)拦截触摸事件。

更多信息在这里

希望能有所帮助。


1
有没有更简单的方法来传递事件以在父视图中触发onClick和onLongClick,还是我必须自己实现它们?
shiami 2010年

检查一下:stackoverflow.com/questions/2136696/pass-event-to-parent-view可能您可能想要尝试将建议的单击侦听器传递给建议的其他实例,即使我不知道它是否会起作用,但可能值得一试。
路易斯·米格尔·塞拉诺

下面的答案更干净
JPM 2013年

我应该实例化MotionEvent吗?请解释@LuisMiguelSerrano
olegario '19

@olegario,通常您使用@O​​verride重新定义例如dispatchTouchEvent的方法,以为其定义新的行为,因此您仅会收到系统已为您的活动(或应用程序的其他组件)提供的运动事件,并且根据您自己的规则对待它和/或转发给任何数量的子组件。像这样的东西: @Override public boolean dispatchTouchEvent(MotionEvent ev) { ... }
Luis Miguel Serrano,

212

TextView使用android:clickable="false"android:focusable="false"v.setClickable(false)和声明您不可点击/不能聚焦的内容v.setFocusable(false)。点击事件应立即发送到TextView的父级。

注意:

为了实现这一点,您必须在其直接栏中添加click parent。或者设置 android:clickable="false"android:focusable="false"其直接父传听众进一步父


1
哦,伙计,如果我能给+100,我会的。一直在尝试找出如何使单击仅在ViewPager中起作用,而在实现onTouch的TouchImageView中不能在适配器布局中起作用!这个解决方案像一个魅力。
JPM

1
但是,如果我想处理EditText的Focus更改事件怎么办?
SweetWisher 1515年

2
场景是:我有一个包含edittext,相对布局,微调器和列表视图的布局。每当我触摸屏幕上除edittext和spinner之外的任何地方时,我都想触发父级布局的touch事件
SweetWisher 2015年

9
东西记住重要的是,如果你使用TextView#setOnClickListener()TextView,就变成可点击的,即使它被声明为android:clickable="false",而且即使在ClickListener设置为nullsetOnclickListener(null)
克里斯蒂安·加西亚

3
有趣的事实:如果在TextView中有一个android:inputType属性,即使使用clickable:false和focusable:false,它也会以静默方式使用click事件。在我的情况下,它设置为一种样式,花了30分钟找出原因。
Kirill Karmazin

18

有时只有这样有帮助:

View child = parent.findViewById(R.id.btnMoreText);
    child.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            View parent = (View) v.getParent();
            parent.performClick();
        }
    });

另一个变体并不总是起作用:

child.setOnClickListener(null);

这似乎CardView作为子视图起作用,因为CardView似乎忽略了clickable="false"focusable="false"。但是,使用setOnTouchListener并调用onTouchEvent父级可以让父级显示触摸反馈(例如波纹效果)。
methodsignature

我在下面发布了相关代码:stackoverflow.com/a/52928884/5652513
methodsignature

10

android:duplicateParentState="true"

在子级中,视图从其直接父级而不是其自身获得其可绘制状态(聚焦,按下等)。您可以为父级设置onclick,然后调用被点击的子级


OP希望在孩子被点击时调用父级的点击监听器,反之则不然。
法里德


1

该答案与Alexander Ukhov的答案类似,不同的是它使用触摸事件而不是单击事件。这些事件允许父母显示适当的按下状态(例如,涟漪效应)。这个答案也在Kotlin中而不是Java中。

view.setOnTouchListener { view, motionEvent ->
    (view.parent as View).onTouchEvent(motionEvent)
}

0

如果你既想OnTouchOnClick听众对父母和孩子两个视,请使用以下技巧:

  1. 用户ScrollView作为父视图,并在其中将子视图放置在Relative / LinearLayout中。

  2. 将Parent设置为ScrollView,android:fillViewport="true"以使View不会滚动。

  3. 然后将OnTouch侦听器设置为父OnClick视图,将侦听器设置为子视图。并享受两个监听器回调。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.