我想在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上的选择/点击效果?
答案 0 :(得分:0)
之前我遇到过同样的问题。它可能是因为您正在使用的textView的text:textIsSelectable属性。删除它或将其设置为false,它将被解决。
答案 1 :(得分: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();
}
}
答案 2 :(得分:0)
this answer对我有用。我在API19 API26中使用Checkbox
进行测试,CheckedTexView
TextView
全部澄清