2

I have a SpannableString set as the text of my TextView which is inside another view that has a click handler. I've got ClickableSpans inside my text which are, you are right, clickable.

My problem is that I need touch events to be captured in case of a click inside the clickable span and not to propagate to parent view (as the parent has another click handler).

The container view is simply a feed of posts in my app, and those posts can contain hashtags/mentions/links etc. If a user taps a hashtag, they should go to the hashtag which is handled by the clickable span, otherwise, they should go to the post, which is handled by the container itself.

Is there any straightforward mechanism to implement this functionality?

Can Poyrazoğlu
  • 33,241
  • 48
  • 191
  • 389

2 Answers2

1

I've came up with a terrible, anti-pattern solution that works well.

In my app class, I've defined:

public static boolean shouldIgnoreNextTouchEvent = false;

In my ClickableSpans click handler, I've set a global flag to avoid next touch event to true:

ClickableSpan clickableSpan = new ClickableSpan() {
    @Override
    public void onClick(View widget) {
        App.shouldIgnoreNextTouchEvent = true;
        ...
    }
 }

Then in my parent view's handler:

@Override
public void onClick() {
    if(App.shouldIgnoreNextTouchEvent){
        App.shouldIgnoreNextTouchEvent = false;
        return;
    }
    ...
}

I know it's not a good solution but it works like a charm.

Can Poyrazoğlu
  • 33,241
  • 48
  • 191
  • 389
0

Alternately,

  1. Add a tag to the widget that generated the click event

`

 ClickableSpan clickableSpan = new ClickableSpan() {
           @Override
            public void onClick(View widget) {
                widget.setTag("hashtag"); // or anything else
            }
     }

`

  1. In the parent, check if the tag is present. If it is, this has been consumed by the ClickableSpan

`

 @Override
    public void onClick(View view) {
        String tag = (String) view.getTag();
        if(tag.equals("hashtag"){
            // Already consumed by child (ClickableSpan)
            return;
        }
        // rest of your code ...
    }

`