How to clear URLSpan click effect?

Background

I wanted to use some URLSpan inside a textView, so I used something like:

final Spanned spanned=Html.fromHtml(getString(R.string.test));
msgTextView.setText(spanned);

Problem

It works, but when you click on an item, it remains pressed. it's as if i still touch the link ...

What i tried

I tried to clear the focus from the textView and set the focus to a different view, but none of them helped.

I also tried to remove UrlSpan and add a new one instead of it every time it is clicked, but it does not work. Here is the code:

  public static Spannable setOnLinkClickedListener(final Spanned original,final IOnLinkClickListener listener)
    {
    final SpannableString result=new SpannableString(original);
    final URLSpan[] spans=result.getSpans(0,result.length(),URLSpan.class);
    for(final URLSpan span : spans)
      {
      final int start=result.getSpanStart(span);
      final int end=result.getSpanEnd(span);
      final int flags=result.getSpanFlags(span);
      result.removeSpan(span);
      final String url=span.getURL();
      result.setSpan(new CustomURLSpan(url,start,result,end,listener,flags),start,end,flags);
      }
    return result;
    }

  private static final class CustomURLSpan extends URLSpan
    {
    private final int                  _start;
    private final SpannableString      _result;
    private final String               _url;
    private final int                  _end;
    private final IOnLinkClickListener _listener;
    private final int                  _flags;

    private CustomURLSpan(final String url,final int start,final SpannableString result,final int end,final IOnLinkClickListener listener,final int flags)
      {
      super(url);
      _start=start;
      _result=result;
      _url=url;
      _end=end;
      _listener=listener;
      _flags=flags;
      }

    @Override
    public void onClick(final View widget)
      {
      if(_listener==null||!_listener.onClick(widget,_url))
        super.onClick(widget);
      _result.removeSpan(this);
      _result.setSpan(new CustomURLSpan(_url,_start,_result,_end,_listener,_flags),_start,_end,_flags);
      }
    }

Question

How to clear the selection / click effect that remains on the URLSpan with every click?

+3
source share
3 answers

. , : textIsSelectable textView. false, .

0

LinkMovementMethod onTouchEvent Selection.removeSelection(buffer); link[0].onClick(widget);.

// 1. Subclass LinkMovementMethod.
public class CustomLinkMovementMethod extends LinkMovementMethod {

    // 2. Copy this method from LinkMovementMethod.
    @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);

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

            if (link.length != 0) {
                if (action == MotionEvent.ACTION_UP) {
                    link[0].onClick(widget);
                    Selection.removeSelection(buffer); // 3. Add this line.
                } 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);
    }
}

BTW, ListView, TextView setPressed, invalidate();, ListView setPressed.

public class CustomTextView extends TextView {

    public CustomTextView(Context context) {
        super(context);
    }

    public CustomTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void setPressed(boolean pressed) {
        super.setPressed(pressed);
        invalidate();
    }
}
0

This answer works for me. I test in API19 API26 with Checkbox, CheckedTexView TextViewall clarifies

0
source

All Articles