一个TextView可以select并包含链接?

我遇到了与TextView的问题。 我可以使用setTextIsSelectable(true)进行select,但是当我通过setMovementMethod(LinkMovementMethod.getInstance())启用链接时,它不再是可选的。

请注意,我并不是说要使原始链接可点击,而是通过使用类似setText(Html.fromHtml("<a href='http://stackoverflow.com'>Hello World!</a>"))

Solutions Collecting From Web of "一个TextView可以select并包含链接?"

oakes的答案会导致textview上的双击

  java.lang.IndexOutOfBoundsException:setSpan(-1 ... -1)在0 ...之前开始 

我查看了LinkMovementMethod中的onTouchEvent实现 ,发现它在textview不包含链接时删除select。 在这种情况下,用户尝试更改时,将从空值和应用程序崩溃开始进行select。

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

所以我重写onTouchEvent方法,它工作正常。

 public class CustomMovementMethod extends LinkMovementMethod { @Override public boolean canSelectArbitrarily () { return true; } @Override public void initialize(TextView widget, Spannable text) { Selection.setSelection(text, text.length()); } @Override public void onTakeFocus(TextView view, Spannable text, int dir) { if ((dir & (View.FOCUS_FORWARD | View.FOCUS_DOWN)) != 0) { if (view.getLayout() == null) { // This shouldn't be null, but do something sensible if it is. Selection.setSelection(text, text.length()); } } else { Selection.setSelection(text, text.length()); } } @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); } else if (action == MotionEvent.ACTION_DOWN) { Selection.setSelection(buffer, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0])); } return true; } } return Touch.onTouchEvent(widget, buffer, event); } } 

希望这对别人有帮助。

我想到了。 您需要inheritanceLinkMovementMethod并添加对文本select的支持。 真的很不幸,它本身不支持它。 我只是用ArrowKeyMovementMethod的源代码覆盖了相关的方法。 我想这是Android开源的好处之一!

 public class CustomMovementMethod extends LinkMovementMethod { @Override public boolean canSelectArbitrarily () { return true; } @Override public void initialize(TextView widget, Spannable text) { Selection.setSelection(text, text.length()); } @Override public void onTakeFocus(TextView view, Spannable text, int dir) { if ((dir & (View.FOCUS_FORWARD | View.FOCUS_DOWN)) != 0) { if (view.getLayout() == null) { // This shouldn't be null, but do something sensible if it is. Selection.setSelection(text, text.length()); } } else { Selection.setSelection(text, text.length()); } } } 

要使用它,直接实例化它,如下所示:

 textView.setMovementMethod(new CustomMovementMethod()); 

LinkMovementMethod()不支持文本select,即使我们可以select文本,但在滚动textview之后,select将会丢失。

最好的实现是从支持文本select的ArrowKeyMovementMethod扩展。

请看这里的细节

XML TextView不应该有任何可以select的链接或属性:

 <TextView android:layout_width="match_parent" android:layout_height="wrap_content"/> 

然后,以编程方式设置所有内容,遵循以下顺序:

 textView.setText(Html.fromHtml(myHtml)); Linkify.addLinks(textView, Linkify.WEB_URLS); textView.setTextIsSelectable(true); // API-11 and above textView.setMovementMethod(LinkMovementMethod.getInstance()); 

有可能将TextView与URL相关联吗? 你是否有10个TextView和10个URL应该是简单的编写代码,如果单击TextView [3]它引发的web浏览器(或浏览器)的意图与URL [3]