3

背景

我想在 textView 中使用一些 URLSpan,所以我使用了类似的东西:

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

问题

它可以工作,但是当单击一个项目时,它会保持单击状态。好像我还在触摸链接...

我试过的

我试图从 textView 中清除焦点并将焦点设置在另一个视图上,但这些都没有帮助。

我还尝试删除 UrlSpan 并添加一个新的,每次单击它时,它都不起作用。这是代码:

  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);
      }
    }

问题

如何清除每次单击时保留在 URLSpan 上的选择/单击效果?

4

3 回答 3

0

我以前也有同样的问题。这可能是因为您正在使用的 textView 的 android:textIsSelectable 属性。删除它或将其设置为false,它将被解决。

于 2014-04-15T11:07:13.730 回答
0

子类化LinkMovementMethod并覆盖onTouchEvent以调用Selection.removeSelection(buffer);after 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);
    }
}

顺便说一句,如果您在ListView、 子类中使用它TextView并覆盖setPressed到 call 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();
    }
}
于 2016-04-13T00:47:17.263 回答
0

这个答案对我有用。我在 API19 API26 中测试CheckboxCheckedTexView TextView都澄清了

于 2017-09-16T08:17:32.437 回答