安卓:文本视图超链接

57

我知道如果在TextView中插入链接是可以生效的,但如果我想要显示例如:

谷歌 堆栈溢出

而不是整个链接(只显示标签),我该如何让这些链接可点击?


请查看此链接:https://dev59.com/6nE85IYBdhLWcg3whT5r#2746708 - Emran
可能是重复的问题:如何使TextView中的链接可点击? - CAMOBAP
这里的一些答案调用了Html.fromHtml,并且要么不使用strings.xml来处理超文本,要么在XML中混淆超文本(例如,在XML文件中将“<”替换为“<”)。这样做会使事情变得不必要地复杂。据我所知,最正确的答案是直接在strings.xml中键入HTML锚标记,确保TextView的autolink属性未设置,然后使用setMovementMethod设置LinkMovementMethod。已经有几个答案展示了如何做到这一点。 - monkey0506
可能是在Android中创建超链接TextView的重复问题。 - Ciro Santilli OurBigBook.com
9个回答

65

如果需要,您可以有两个单独的TextView,并在布局中相应地对齐它们:

    Text1.setText(
        Html.fromHtml(
            "<a href=\"http://www.google.com\">google</a> "));
    Text1.setMovementMethod(LinkMovementMethod.getInstance());

    Text2.setText(
            Html.fromHtml(
                "<a href=\"http://www.stackoverflow.com\">stackoverflow</a> "));
    Text2.setMovementMethod(LinkMovementMethod.getInstance());

如果你想去掉“链接下划线”,可以创建一个类:

public class URLSpanNoUnderline extends URLSpan {
    public URLSpanNoUnderline(String url) {
        super(url);
    }
    @Override public void updateDrawState(TextPaint ds) {
        super.updateDrawState(ds);
        ds.setUnderlineText(false);
        }
}

然后在你的主Activity类中添加此方法,该类应该包含TextViews。

private void stripUnderlines(TextView textView) {
    Spannable s = new SpannableString(textView.getText());
    URLSpan[] spans = s.getSpans(0, s.length(), URLSpan.class);
    for (URLSpan span: spans) {
        int start = s.getSpanStart(span);
        int end = s.getSpanEnd(span);
        s.removeSpan(span);
        span = new URLSpanNoUnderline(span.getURL());
        s.setSpan(span, start, end, 0);
    }
    textView.setText(s);
}

在你的onCreate方法中初始化TextViews后,只需调用以下代码:

stripUnderlines(Text1);
stripUnderlines(Text2);

2
注意:如果您在TextView的属性中设置了autolink,则此方法将无法正常工作!如果有设置,您必须在调用setText()之前调用textView.setAutoLinkMask(0); - Xebozone
如果您需要翻译资源,我不建议使用这种解决方案。 - StarWind0

61
TextView t2 = (TextView) findViewById(R.id.textviewidname);
t2.setMovementMethod(LinkMovementMethod.getInstance());
并且
<string name="google_stackoverflow"><a href="https://dev59.com/r2kw5IYBdhLWcg3wfKrZ">google stack overflow</a></string>

这个链接是"Android: textview hyperlink"

并且标签为"google stack overflow"

请在Java文件中定义第一个代码块,在strings.xml文件中定义第二个代码块。同时确保在Java中引用了页面布局的textView的ID。


4
我最喜欢你的方式。依我之见,这是最简洁明了的方法。 - plackemacher
这适用于多个链接。例如 <string name="name">示例:<a href="http://www.link1.com">链接1</a> 和 <a href="http://www.link2.com">链接2</a></string> - Peter
1
同时,数据绑定也能很好地工作:只需为类似“containsLinks”的属性定义一个BindingAdapter,然后在适配器中设置移动方法即可。 - ubuntudroid

19

android:autoLink="web" 只有当你在HTML中使用完整的链接时才会生效。以下内容将会被标记为蓝色并可点击:


17

非常简单的方法:

在你的 Activity 中--

 TextView tv = (TextView) findViewById(R.id.site);
 tv.setText(Html.fromHtml("<a href=http://www.stackoverflow.com> STACK OVERFLOW "));
 tv.setMovementMethod(LinkMovementMethod.getInstance());

那么你将只得到标签,而不是整个链接。

希望会对你有帮助...


7
这应该可以工作。
TextView t2 = (TextView) findViewById(R.id.text2);
t2.setMovementMethod(LinkMovementMethod.getInstance());

and

<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="@string/txtCredits"
android:id="@+id/text2"
 android:layout_centerInParent="true"
android:layout_marginTop="20dp"></TextView>

是的,你可以将此包含在你的字符串资源中: <string name="txtCredits"><a href="http://www.google.com">谷歌</a></string>。 - Anurag Ramdasan
3
请确保您没有在自动链接属性中选择任何内容。如果自动链接属性中有任何内容被选择,LinkMovementMethod.getInstance() 无法在该textview中起作用。 - Ram G.

3
这是我的工作实现。
private void showMessage()
    {

        lblMessage.setText("");

        List<String> messages = db.getAllGCMMessages();

        for (int k = messages.size() - 1; k >= 0; --k)
         {

            String message  =  messages.get(k).toString();
            lblMessage.append(message + "\n\n");

         }
     Linkify.addLinks(lblMessage, Linkify.ALL);
  }

为了改变超链接的颜色,我编辑了我的TextView的XML-

 android:textColorLink="#69463d"

3
数据绑定怎么样?
@JvmStatic
@BindingAdapter("textHtml")
fun setHtml(textView: TextView, resource: String) {
    val html: Spanned = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        Html.fromHtml(resource, Html.FROM_HTML_MODE_COMPACT)
    } else {
        Html.fromHtml(resource)
    }

    textView.movementMethod = LinkMovementMethod.getInstance()
    textView.text = html
}

strings.xml

<string name="text_with_link">&lt;a href=%2$s>%1$s&lt;/a> </string>

在你的layout.xml文件中

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:textHtml="@{@string/text_with_link(model.title, model.url)}"
            tools:text="Some text" />

xml中的标题和链接是简单的字符串

此外,您可以向数据绑定适配器传递多个参数

@JvmStatic
@BindingAdapter(value = ["textLink", "link"], requireAll = true)
fun setHtml(textView: TextView, textLink: String?, link: String?) {
    val resource = String.format(textView.context.getString(R.string.text_with_link, textLink, link))

    val html: Spanned = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        Html.fromHtml(resource, Html.FROM_HTML_MODE_COMPACT)
    } else {
        Html.fromHtml(resource)
    }

    textView.movementMethod = LinkMovementMethod.getInstance()
    textView.text = html
}

在 .xml 文件中,参数需要分开传递。
        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:link="@{model.url}"
            app:textLink="@{model.title}"
            tools:text="Some text" />

2
使用
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:autoLink="web"
    android:text="www.google.com" />

这个标志

autolink="web"

控制是否自动查找并将诸如网址之类的链接转换为可点击的链接。默认值为“none”,禁用此功能。 取值:all,email,map,none,phone,web。


2
我遇到了相同的问题,最终找到了可行的解决方案。
  1. in the string.xml file, define:

    <string name="textWithHtml">The URL link is &lt;a href="http://www.google.com">Google&lt;/a></string>
    

将"<"小于符号替换为HTML转义字符。

  1. In Java code:

    String text = v.getContext().getString(R.string.textWithHtml);
    textView.setText(Html.fromHtml(text));
    textView.setMovementMethod(LinkMovementMethod.getInstance());
    

文本框将正确显示带有可点击的超链接的文本


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接