How to pass a view's onClick event to its parent on Android?

119,818

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.

Share:
119,818

Related videos on Youtube

shiami
Author by

shiami

Updated on July 08, 2022

Comments

  • shiami
    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
    shiami over 13 years
    Is 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
    Luis Miguel Serrano over 13 years
    Check this out: stackoverflow.com/questions/2136696/pass-event-to-parent-vie‌​w 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
    JPM over 10 years
    Oh 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
    JPM over 10 years
    Answer below is much cleaner
  • Rooster242
    Rooster242 almost 10 years
    Works perfectly. Much better than the excepted answer.
  • SweetWisher ツ
    SweetWisher ツ over 9 years
    but what if I want to handle Focus change event of EditText ?
  • siyb
    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 ツ
    SweetWisher ツ over 9 years
    The 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
    Orkun Ozen about 9 years
    Why wonT this work for a ListView instead of a TextView? anyone?
  • Christian García
    Christian García about 9 years
    Something important to bear in mind is that if you use TextView#setOnClickListener() on the TextView, it becomes clickable, even if it's declared as android:clickable="false", and even if the the ClickListener is set to null (setOnclickListener(null))
  • srinivas
    srinivas over 8 years
    But this solution is making the imageView unclickable, and thus only clicking outside the image is triggering the click.
  • An-droid
    An-droid almost 8 years
    What if I want both the parent and the child to intercepte their OnClick ?
  • M.ArslanKhan
    M.ArslanKhan over 7 years
    I 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
    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
    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
    Zar E Ahmer over 7 years
    I 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
    dell116 almost 6 years
    If you don't know why, I recommend you don't do it. Just saying...to each his own.
  • Kirill Karmazin
    Kirill Karmazin over 5 years
    Fun 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
    methodsignature over 5 years
    This worked for CardView as the child view, since CardView seems to ignore clickable="false" and focusable="false". However, using setOnTouchListener and calling onTouchEvent on the parent instead allows the parent to display touch feedback (e.g. ripple effect).
  • methodsignature
    methodsignature over 5 years
    I posted relevant code below: stackoverflow.com/a/52928884/5652513.
  • olegario
    olegario about 5 years
    Should I instantiate the MotionEvent? Please, explain, @LuisMiguelSerrano
  • Luis Miguel Serrano
    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
    Farid about 4 years
    OP wants to call parent's click listener when child is clicked, not wise versa.
  • AZ_
    AZ_ about 4 years
    You should set it to android:inputType="none"
  • Nil
    Nil over 3 years
    I had same issue. In textview I have set android:inputType="textCapWords"
  • DmitryKanunnikoff
    DmitryKanunnikoff over 3 years
    Helpful 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()