Expand touch area of ClickableSpan
Asked Answered
N

1

10

I have a TextView in which I set HTML text. This text has many links. When you tap a link, it does not always trigger the onClick method. So, I am trying to expand the area of ClickableSpan, so that it is always responsive.

int start = strBuilder.getSpanStart(span);
int end = strBuilder.getSpanEnd(span);
int flags = strBuilder.getSpanFlags(span);
final ClickableSpan clickable = new ClickableSpan() {
  public void onClick(View view) {
    getTouchActions(span.getURL());
  }
};
strBuilder.setSpan(clickable, start, end, flags);
strBuilder.removeSpan(span);
Nursling answered 3/10, 2014 at 13:44 Comment(2)
create a custom MovementMethod, extend this: github.com/android/platform_frameworks_base/blob/master/core/…Valedictory
Odys, do you mind sharing a snippet of your solution?Cigar
N
8

The CustomMovementMethod has to extend ScrollingMovementMethod and override the onTouchEvent method. In order to add some extra space you have to define it in you dimensions and use that in the start/end span.

@Override
  public boolean onTouchEvent(TextView widget, Spannable buffer,
                              MotionEvent event) {
int action = event.getAction();

if (action == MotionEvent.ACTION_UP ||
    action == MotionEvent.ACTION_DOWN) {
  int x = (int) event.getX();
  int y = (int) event.getY();

  x -= widget.getTotalPaddingLeft();
  y -= widget.getTotalPaddingTop();

  x += widget.getScrollX();
  y += widget.getScrollY();

  Layout layout = widget.getLayout();
  int line = layout.getLineForVertical(y);
  int off = layout.getOffsetForHorizontal(line, x);

  int startSpan = off - context.getResources().getDimension(R.dimen.extra_space_start);
  int endSpan = off + context.getResources().getDimension(R.dimen.extra_space_end);

  ClickableSpan[] link = buffer.getSpans(startSpan, endSpan, ClickableSpan.class);

  if (link.length != 0) {
    if (action == MotionEvent.ACTION_UP) {
      link[0].onClick(widget);
    } else if (action == MotionEvent.ACTION_DOWN) {
      Selection.setSelection(buffer,
          buffer.getSpanStart(link[0]),
          buffer.getSpanEnd(link[0]));
    }

    return true;
  } else {
    Selection.removeSelection(buffer);
  }
}

return super.onTouchEvent(widget, buffer, event);

}

You can call your custom link movement like this:

textView.setMovementMethod(new CustomLinkMovementMethod(context));
textView.setLinksClickable(true);
Nursling answered 2/1, 2015 at 9:29 Comment(1)
This only increases clickable area horizontally (to left and right of the regular clickable space). Also, using dimensions like extra_space_start is misleading: getOffsetForHorizontal returns offset as a number of characters. Also, getSpans requires character indices, not dimensions. So this solution mixes dimensions with indices.Barrel

© 2022 - 2024 — McMap. All rights reserved.