How to pass a view's onClick event to its parent on Android?
Solution 1
I think you need to use one of those methods in order to be able to intercept the event before it gets sent to the appropriate components:
Activity.dispatchTouchEvent(MotionEvent)
- This allows your Activity to intercept all touch events before they are dispatched to the window.
ViewGroup.onInterceptTouchEvent(MotionEvent)
- This allows a ViewGroup to watch events as they are dispatched to child Views.
ViewParent.requestDisallowInterceptTouchEvent(boolean)
- Call this upon a parent View to indicate that it should not intercept touch events with onInterceptTouchEvent(MotionEvent).
More information here.
Hope that helps.
Solution 2
Declare your TextView
not clickable / focusable by using android:clickable="false"
and android:focusable="false"
or v.setClickable(false)
and v.setFocusable(false)
. The click events should be dispatched to the TextView
's parent now.
Note:
In order to achieve this, you have to add click to its direct parent
. or set
android:clickable="false"
and android:focusable="false"
to its direct parent to pass listener to further parent.
Solution 3
Sometime only this helps:
View child = parent.findViewById(R.id.btnMoreText);
child.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
View parent = (View) v.getParent();
parent.performClick();
}
});
Another variant, works not always:
child.setOnClickListener(null);
Solution 4
Put
android:duplicateParentState="true"
in child then the views get its drawable state (focused, pressed, etc.) from its direct parent rather than from itself. you can set onclick for parent and it call on child clicked
Solution 5
If your TextView
create click issues, than remove android:inputType=""
from your xml file.
Related videos on Youtube
shiami
Updated on July 08, 2022Comments
-
shiami almost 2 years
I have a TextView in a layout whos background is a Selector. And the TextView's text is set to Spanned from HTML. Then I set the TextView with the LinkMovementMethod.
Now when I tap on the TextView, the click event is not sent to its parent layout to trigger the selector.
How should this be solved?
-
shiami over 13 yearsIs there an easier way to pass the events to trigger the onClick and onLongClick in parent view, or I have to implement them myself?
-
Luis Miguel Serrano over 13 yearsCheck this out: stackoverflow.com/questions/2136696/pass-event-to-parent-view Possibly you might want to try passing the same click listener to the other instances as suggested, even though I don't know if it will work, but might be worth a try.
-
JPM over 10 yearsOh man if I could give this +100 I would. Been trying to figure out how to make a click only work in a ViewPager and not in the adapters layout with TouchImageView implementing onTouch! This solution worked like a charm.
-
JPM over 10 yearsAnswer below is much cleaner
-
Rooster242 almost 10 yearsWorks perfectly. Much better than the excepted answer.
-
SweetWisher ツ over 9 yearsbut what if I want to handle Focus change event of EditText ?
-
siyb over 9 years@SweetWisherヅ: please provide some source code and explain your problem in detail. In general, dispatching events from views might also work, but I cannot help you unless you provide more useful information.
-
SweetWisher ツ over 9 yearsThe scenario is : I have a layout which contains edittext ,relative layout, spinner and list view. I want to fire touch event of parent layout whenever i touch on anywhere on the screenexcept the edittext and spinner
-
Orkun Ozen about 9 yearsWhy wonT this work for a ListView instead of a TextView? anyone?
-
Christian García about 9 yearsSomething important to bear in mind is that if you use
TextView#setOnClickListener()
on theTextView
, it becomes clickable, even if it's declared asandroid:clickable="false"
, and even if the theClickListener
is set tonull
(setOnclickListener(null)
) -
srinivas over 8 yearsBut this solution is making the imageView unclickable, and thus only clicking outside the image is triggering the click.
-
An-droid almost 8 yearsWhat if I want both the parent and the child to intercepte their OnClick ?
-
M.ArslanKhan over 7 yearsI want to pass the onclick event to the parent but I Don't need to pass this event while Onlong press. what is the best solution. your solution is best for only onclick event
-
siyb over 7 years@Tarikhelian: I would suggest using RecyclerView now, it allows you to be more flexible in this regard. Basically you would first declare all child views clickable=false and focusable=false and set a OnLongClickListener / OnClickListener on the parent view. Hope that helps.
-
siyb over 7 years@Nepster: I don't get what you are trying to say with your edit, are you talking about dispatching a click event to a parent view further up the hierarchy (referring to: "add click")? Please clarify. I hope you don't mind me correcting some of the grammatical errors ;).
-
Zar E Ahmer over 7 yearsI have experience that if we set clickable and focusable = false to any View. It retrun false to handle the event. So the event pass to it's parent . And if that parent also don't want to handle the event . they should also set Focusable and clickable = false.
-
dell116 almost 6 yearsIf you don't know why, I recommend you don't do it. Just saying...to each his own.
-
Kirill Karmazin over 5 yearsFun fact: if in TextView there is an
android:inputType
attribute it will silently consume click events even with clickable: false & focusable: false; in my case it was set in a style and it cost me 30 minutes to figure out the cause. -
methodsignature over 5 yearsThis worked for
CardView
as the child view, sinceCardView
seems to ignoreclickable="false"
andfocusable="false"
. However, usingsetOnTouchListener
and callingonTouchEvent
on the parent instead allows the parent to display touch feedback (e.g. ripple effect). -
methodsignature over 5 yearsI posted relevant code below: stackoverflow.com/a/52928884/5652513.
-
olegario about 5 yearsShould I instantiate the MotionEvent? Please, explain, @LuisMiguelSerrano
-
Luis Miguel Serrano about 5 years@olegario, typically you redefine the method for example for dispatchTouchEvent, with @Override, to define a new behavior for it, so you just receive a motion event the system has provided to your activity (or another component of your application), and you treat it and/or forward to any number of children components according to your own rules. Something like:
@Override public boolean dispatchTouchEvent(MotionEvent ev) { ... }
-
Farid about 4 yearsOP wants to call parent's click listener when child is clicked, not wise versa.
-
AZ_ about 4 yearsYou should set it to
android:inputType="none"
-
Nil over 3 yearsI had same issue. In textview I have set
android:inputType="textCapWords"
-
DmitryKanunnikoff over 3 yearsHelpful answer, thanks! But I would suggest the following clarifications: 1) use other name for touched view - 'touchedView', for example; 2) call performClick() instead of onTouchEvent()