如何使TextView中的链接可点击?


1003

我定义了以下TextView:

<TextView android:layout_width="wrap_content"
    android:layout_height="wrap_content" android:text="@string/txtCredits"
    android:autoLink="web" android:id="@+id/infoTxtCredits"
    android:layout_centerInParent="true"
    android:linksClickable="true"></TextView>

哪里@string/txtCredits是包含的字符串资源<a href="some site">Link text</a>

Android会突出显示TextView中的链接,但它们不会响应点击。有人可以告诉我我在做什么错吗?我是否必须为我的活动中的TextView设置onClickListener,就像这样简单?

看起来它与我定义字符串资源的方式有关。这不起作用:

<string name="txtCredits"><a href="http://www.google.com">Google</a></string>

但这确实是:

<string name="txtCredits">www.google.com</string>

这真是令人讨厌,因为我宁愿显示文本链接,也不显示完整的URL。


67
android:autoLink =“ web”这是需要添加到xml的主行,它的工作方式类似于charm。感谢@Richard
jeet.chanchawat 2012年

1
<string name =“ txtCredits”> <a href=" google.com"> www.google.com </a> </ string >使用上面的方法,它可以工作。据悉,href和带有锚标记的字符串必须相同,并且具有.com或。*才能正常工作,需要检查原因
Shaik Khader 2013年

<string name =“ txtCredits”>此处的某些文本<a href=" google.com"> Google </a> </ string >对于以上代码段,请单击此处的某些文本在我的情况下不起作用,我该怎么办?
2014年


android:focusable="true"解决了我的问题
Khang .NT

Answers:


1228

埋在API演示中,我找到了解决问题的方法:

Link.java:

    // text2 has links specified by putting <a> tags in the string
    // resource.  By default these links will appear but not
    // respond to user input.  To make them active, you need to
    // call setMovementMethod() on the TextView object.

    TextView t2 = (TextView) findViewById(R.id.text2);
    t2.setMovementMethod(LinkMovementMethod.getInstance());

我删除了TextView上的大多数属性以匹配演示中的内容。

<TextView
    android:id="@+id/text2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/txtCredits"/>

那解决了。很难发现和修复。

重要提示autoLink="web"如果您要打电话,别忘了删除setMovementMethod()


19
也许只有我一个人,但是为什么要使用EditText呢?
贾斯汀

1
事实证明只需要setMovementMethod即可达到目标。
superarts.org 2012年

3
正如commment,我已经看到了一些三星Galaxy S3与OS 4.3是崩溃使用“setMovementMethod(LinkMovementMethod.getInstance())”的时候,所以才考虑到这一点,我已经将它添加之前创建一个验证
豪尔赫阿吉拉尔

40
同样在这里。请注意,如果调用setMovementMethod(),则必须在XML文件中删除autolink =“ web”,否则链接将无法工作。感谢您的评论
voghDev 2014年

6
只需在您的xml中使用“ autoLink”属性即可,例如:android:autoLink =“ web”
Kalpesh 2015年

533

我只用android:autoLink="web"它,它工作正常。单击链接将打开浏览器并显示正确的页面。

我可能猜到的一件事是链接上方有其他视图。透明的内容会填充整个父对象,但在链接上方不会显示任何内容。在这种情况下,单击将转到该视图而不是链接。


3
在上面添加了更多信息。可能是我将字符串定义为<string name =“ txtCredits”> <a href=" google.com"> Google </a> </ string >的方式吗?看起来这是允许的,但对我不起作用。
理查德

6
如果使用linkify auto,则不需要href部分。操作系统将使用字符串对其解析以获取网址,并将每个网址转换为可点击的链接。但这不会导致google这个词链接到google.com。它将显示www.google.com作为链接。
Janusz

使用自动链接对我也很完美,纯文本视图完全没有父级。
euther 2011年

2
android:autoLink也非常适合链接电话号码,地址和电子邮件地址(或以上所有地址)。
CloudyMusic 2012年

54
不,不是这样,因为如果您不希望使用锚文本和URL
以外的

375

花了一些时间后,我发现:

  • android:autoLink="web"如果您的HTML中有完整链接,则可以使用。以下内容将以蓝色突出显示并单击:
  • 一些文字 <a href="http://www.google.com">http://www.google.com</a>
  • 一些文字 http://www.google.com
  • view.setMovementMethod(LinkMovementMethod.getInstance()); 将与以下内容一起使用(将突出显示并单击):
  • 一些文字 <a href="http://www.google.com">http://www.google.com</a>
  • 一些文字 http://www.google.com
  • 一些文字 <a href="http://www.google.com">Go to Google</a>

请注意,第三个选项具有超链接,但是链接的描述(标签之间的部分)本身不是链接。android:autoLink="web"确实不是这样的联系工作。

  • android:autoLink="web"如果以XML设置,则会覆盖view.setMovementMethod(LinkMovementMethod.getInstance());(即,第三种链接将突出显示,但不可点击)。

这个故事的寓意是view.setMovementMethod(LinkMovementMethod.getInstance());在代码中使用,android:autoLink="web"如果您希望所有链接都可单击,请确保您不在XML布局中。


setMovementMethod不适用于您提到的第二个选项,即google.com ..是否有任何更新?
达尔潘(Darpan)2015年

16
感谢您指出对<a href="http://www.google.com">Go to Google</a>自动链接无效。对于SO的这么多答案,这是唯一提及它的人。谢谢!
cwhsu

这个作品。测试在API 29
Wrichik八宿

96

上面的解决方案对我来说不起作用,但是下面的解决方案却可行(而且看起来更干净)。
首先,在字符串资源中,使用HTML实体编码来定义标签开头的V形,即:

&lt;a href="http://www.google.com">Google&lt;/a>

并不是:

<a href="http://www.google.com">Google</a>

通常,像这样对字符串中的所有V形符号进行编码。顺便说一句,链接必须以http://

然后(如建议在这里)设置你的TextView此选项:

 android:linksClickable="true"

最后,在代码中执行以下操作:

((TextView) findViewById(R.id.your_text_view)).setMovementMethod(LinkMovementMethod.getInstance());
((TextView) findViewById(R.id.your_text_view)).setText(Html.fromHtml(getResources().getString(R.string.string_with_links)));

就是这样,不需要正则表达式或其他手动技巧。


7
每当执行此代码时,这将创建一个HTML解析器。请注意,如果您使用它在列表项内或应用程序中其他性能至关重要的位置创建链接。在创建列表项的过程中,这会使我的getView方法的执行时间缩短了50%
Janusz 2012年

1
另请注意,URL中的空格必须替换为%20
Nicolas Tyler

您可以通过将字符串包装在<![CDATA[ ... ]]>标记中来避免实体编码问题。
Paul Lammertsma 2014年

1
为我工作,谢谢。无法使用<![CDATA[...]]>标签。
ricky.tribbia 2015年

这应该是答案!我的本机应用程序工作得很好
阿贾伊·库尔卡尼

68

我只是用这个

Linkify.addLinks(TextView, Linkify.ALL);

使链接可点击此处给出


4
这个答案是最好的。适用于所有Android版本,当TextView中的文本设置为set时,我们只需要添加该方法即可。奖励:它允许我们添加可点击的可自定义链接
Kerwan 2014年

3
真正最简单,最好的答案。它同时适用于电子邮件/网络。
Imran Ahmed

1
使用LinkifyCompat如果你需要一些较新的高级功能
Vaiden

好的,它使网址无法<a href...点击
Pavel

这也使得内工作的所有“HTML”标签。因此,如<B> ... </ B>等
阵列

67

如果要添加类似HTML的链接,您需要做的是:

  • 添加类似HTML的资源字符串:

     <string name="link"><a href="https://www.google.pl/">Google</a></string>
  • 完全不使用链接特定的配置即可将视图添加到布局中:

     <TextView
        android:id="@+id/link"
        android:text="@string/link" />`
  • 以编程方式将适当的MovementMethod添加到TextView中:

     mLink = (TextView) findViewById(R.id.link);
     if (mLink != null) {
       mLink.setMovementMethod(LinkMovementMethod.getInstance());
     }

而已!是的,让“ autoLink”和“ linksClickable”之类的选项仅在显式链接上工作(未包装到html标签中)对我也很容易产生误解。


2
+1你是对的。应该有一个选项可以输入自己的模式,以便与之匹配。这样真是愚蠢。
schlingel

47

我将此行添加到TextViewandroid:autoLink="web"
以下是布局文件中用法的示例。

layout.xml 样品

    <TextView
        android:id="@+id/txtLostpassword"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:autoLink="email"
        android:gravity="center"
        android:padding="20px"
        android:text="@string/lostpassword"
        android:textAppearance="?android:attr/textAppearanceSmall" />

    <TextView
        android:id="@+id/txtDefaultpassword"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:autoLink="web"
        android:gravity="center"
        android:padding="20px"
        android:text="@string/defaultpassword"
        android:textAppearance="?android:attr/textAppearanceSmall" />

string.xml

<string name="lostpassword">If you lost your password please contact <a href="mailto:support@cleverfinger.com.au?Subject=Lost%20Password" target="_top">support@cleverfinger.com.au</a></string>

<string name="defaultpassword">User Guide <a href="http://www.cleverfinger.com.au/user-guide/">http://www.cleverfinger.com.au/user-guide/</a></string>

36

以下内容适用于在Android应用程序中查找文本和超链接组合的任何人。

string.xml

<string name="applink">Looking for Digital Visiting card? 
<a href="https://play.google.com/store/apps/details?id=com.themarkwebs.govcard">Get it here</a>
</string>

现在,您可以string在任何给定的View像这样的环境中使用它:

<TextView
    android:id="@+id/getapp"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:gravity="center"
    android:textColor="@color/main_color_grey_600"
    android:textSize="15sp"
    android:text="@string/applink"/>

现在,在“活动”或“片段”中,执行以下操作:

TextView getapp =(TextView) findViewById(R.id.getapp);
getapp.setMovementMethod(LinkMovementMethod.getInstance());

到目前为止,您无需设置android:autoLink="web"android:linksClickable="true"使用此方法。

希望对您有所帮助。


这很好用,但是当您从网络上按回去时,仅关闭浏览器,而不返回到应用程序。
Jachumbelechao到Mantekilla

27

我希望这能帮到您;

String value = "<html>Visit my blog <a href=\"http://www.maxartists.com\">mysite</a> View <a href=\"sherif-activity://myactivity?author=sherif&nick=king\">myactivity</a> callback</html>";
    TextView text = (TextView) findViewById(R.id.text);


    text.setText(Html.fromHtml(value));
    text.setMovementMethod(LinkMovementMethod.getInstance());

3
这很棒。另外,请确保您android:autoLink=?从中删除TextView
sulai

这终于对我有用。有效的HTML并且不使用android:autoLink=?很重要!
Neal Sanche

对于Xamarin,该单词显示但未加下划线,并且不能使用上述参数而不是以下参数来单击:autoLink,linksClickable
maxweber 2013年

对于Xamarin,设置这些字符并设置Text或设置TextFormatted也会产生该单词,但该单词不可单击,也不可带有蓝色/下划线。删除自动链接也会失败。仅删除linksClickable也会失败。删除两者也失败。
maxweber 2013年

helloWorld.TextFormatted = Html.FromHtml(linkURL); 有和没有那些也失败了。(未链接,不是蓝色,无法单击)
maxweber


24

对我来说最简单的方法是使用Linkify

TextView txt_Message = (TextView) view.findViewById(R.id.txt_message);
txt_Message.setText("This is link https://www.google.co.in/");
Linkify.addLinks(txt_Message, Linkify.WEB_URLS);

它将自动从textview中的文本中检测Web网址。


是的,但它们不会被点击。
FractalBob

链接是可单击的。
Octavian Ionel'9

19

理查德,下一次,您应该改为在布局XML的TextView下添加此代码。

android:autoLink="all"

应该是这样的。

<TextView 
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" 
    android:text="@string/txtCredits"
    android:id="@+id/infoTxtCredits"
    android:autoLink="all"
    android:linksClickable="true">
</TextView>

您无需使用此代码(t2.setMovementMethod(LinkMovementMethod.getInstance());)即可使链接可点击。

另外,这是事实:只要设置了autoLinklinksClickable,别忘了在String.xml文件中添加它,以便clickable链接起作用。

<string name="txtCredits"><a href="http://www.google.com">Google</a></string>

3
对我不起作用。该链接的确可以单击,但是会显示整个字符串,而不仅仅是“ Google”。实际上,到目前为止,这里没有任何答案或其组合有效。
紫罗兰色长颈鹿

您的设备或模拟器是否已启用Internet并将其设置为ON(wifi)或已连接局域网@Violet Giraffe?
大卫·迪玛兰塔

它是。我从来没有设法仅使用XML属性就使链接可点击,而不得不求助于Java代码。没什么大不了的,但是不好。
紫罗兰色长颈鹿

18

通过使用linkify Linkify接受一段文本和一个正则表达式,并将文本中的所有正则表达式匹配项转换为可点击的链接

TextView textView = (TextView) findViewById(R.id.textView);
textView.setText("http://www.domain.com");
Linkify.addLinks(textView, Linkify.WEB_URLS);

别忘了

import android.widget.TextView;

16

这是非常一行的android代码,无论字符串和数据是什么,都可以从textView中选择电话和url。您不需要为此使用任何HTML标记。

TextView textView = (TextView)findViewById(R.id.textView1);
textView.setText("some url is www.google.com phone 7504567890 another url lkgndflg.com ");

// Makes the textView's Phone and URL (hyperlink) select and go.
Linkify.addLinks(textView, Linkify.WEB_URLS | Linkify.PHONE_NUMBERS);

13

我注意到,使用android:autoLink="web"这样

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

工作确定的网址,但因为我有一个电子邮件地址和电话号码,我想链接,以及,我结束了使用此行android:autoLink="all"像这样

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

它就像一种魅力。


13

同时管理Linkify文字颜色 在此处输入图片说明

tv_customer_care_no.setLinkTextColor(getResources().getColor(R.color.blue));
  tv_customer_care_no.setText("For us to reach out to you, please fill the details below or contact our customer care at  18004190899 or visit our website http://www.dupont.co.in/corporate-links/contact-dupont.html ");
   Linkify.addLinks(tv_customer_care_no, Linkify.WEB_URLS | Linkify.PHONE_NUMBERS);
   Linkify.addLinks(tv_customer_care_no, Linkify.ALL );

11

确保使用setAutoLinkMask(Linkify.ALL)使用时setMovementMethod(LinkMovementMethod.getInstance())Html.fromHTML()在格式正确的HTML链接(例如,<a href="http://www.google.com/">Google</a>)。


10

用这个...

TextView.setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub
                        Intent in=new Intent(Intent.ACTION_VIEW,Uri.parse("http://www.twitter.com/"));
                        startActivity(in);
                    }

                });

并在清单文件中添加权限

<uses-permission android:name="android.permission.INTERNET"/>

1
这将起作用,但请记住,除了此可单击的TextView外,该应用程序可能不需要Internet权限。在这些情况下,可能过大了
Jose_GD

2
它真的与问题有关吗?
达尔潘(Darpan)2015年

2
这与问题无关。
afollestad 2015年

1
这将永远不会失败!
天网

我喜欢这种方法,因为它允许我们仅显示锚文本而不是完整的URL。锚文本也可以设置样式,例如绿色和带下划线。
失散的婴儿,

10

您只需要这个:

android:autoLink="web"

将此行插入TextView,可以参考Web单击该行。URL地址设置为此TextView的文本。

例:

 <TextView
    android:id="@+id/textViewWikiURL"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="20sp"
    android:textStyle="bold"
    android:text="http://www.wikipedia.org/"
    android:autoLink="web" />

10

可接受的答案是正确的,但是这意味着电话号码,地图,电子邮件地址和常规链接(例如,http://google.com没有href标签)将不再可用,因为您无法在xml中进行自动链接。

我发现,唯一可让所有人点击的完整解决方案如下:

Spanned text = Html.fromHtml(myString);
URLSpan[] currentSpans = text.getSpans(0, text.length(), URLSpan.class);
SpannableString buffer = new SpannableString(text);
Linkify.addLinks(buffer, Linkify.ALL);
for (URLSpan span : currentSpans) {
    int end = text.getSpanEnd(span);
    int start = text.getSpanStart(span);
    buffer.setSpan(span, start, end, 0);
}
textView.setText(buffer);
textView.setMovementMethod(LinkMovementMethod.getInstance());

而且TextView不应该具有android:autolinkandroid:linksClickable="true"两者都不需要。默认情况下是这样。


对我来说,没有这个就可以了,被接受的答案很好@Kelly你能告诉你这个问题的Android版本和设备吗?
阿希尔·爸爸

myapp://方案不起作用(对于深度链接)。
CoolMind

7

这就是我解决TextView中可点击和可见链接的方式(通过代码)

private void setAsLink(TextView view, String url){
        Pattern pattern = Pattern.compile(url);
        Linkify.addLinks(view, pattern, "http://");
        view.setText(Html.fromHtml("<a href='http://"+url+"'>http://"+url+"</a>"));
    }

但我想查看文本,当单击文本时,它会重定向到链接(由浏览器打开)吗?该解决方案不能解决问题,对吗?
Duc Tran 2012年

6

使用以下代码:

String html = "<a href=\"http://yourdomain.com\">Your Domain Name</a>"
TextView textview = (TextView) findViewById(R.id.your_textview_id);
textview.setMovementMethod(LinkMovementMethod.getInstance());
textview.setText(Html.fromHtml(html));

6

[Tested in Pre-lollipop as well as in Lollipop and above]

您可以从后端或资源文件中获取HTML字符串。如果将文本作为资源字符串放置,请确保添加CDATA标签:

<string name="your_text">![CDATA[...<a href="your_link">Link Title</a>  ...]]</string>

然后在代码中,您需要获取字符串并将其分配为HTML并设置链接移动方法:

String yourText = getString(R.string.your_text);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
   textView.setText(Html.fromHtml(yourText, Html.FROM_HTML_MODE_COMPACT));
} else {
   textView.setText(Html.fromHtml(yourText));
}

try {
   subtext.setMovementMethod(LinkMovementMethod.getInstance());
} catch (Exception e) {
   //This code seems to crash in some Samsung devices.
   //You can handle this edge case base on your needs.
}


4

不知道是否值得添加另一个答案,但以防万一...

我不得不在几个地方进行搜索,但最终使此版本的代码生效。

strings.xml:

<string name="name1">&lt;a href="http://www.google.com">link text1&lt;/a></string>
<string name="name2">&lt;a href="http://www.google.com">link text2&lt;/a></string>

myactivity.xml:

<TextView 
    android:id="@+id/textview1"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:layout_marginTop="5dp" />

<TextView 
    android:id="@+id/textview2"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:layout_marginTop="5dp" />

myactivty.java(在onCreate()中):

TextView tv1 = (TextView)findViewById(R.id.textview1);
TextView tv2 = (TextView)findViewById(R.id.textview2);

tv1.setText(Html.fromHtml(getResources().getString(R.string.name1)));
tv2.setText(Html.fromHtml(getResources().getString(R.string.name2)));
tv1.setMovementMethod(LinkMovementMethod.getInstance());
tv2.setMovementMethod(LinkMovementMethod.getInstance());

这将创建一个文本的两种可点击超链接link text1link text2该用户重定向到谷歌。


4

自动链接电话不适用于我。以下作品颇具魅力,

TextView tv = (TextView) findViewById(R.id.emergencynos);
String html2="<br><br>Fire - <b><a href=tel:997>997</a> </b></br></br>";        
tv.append(Html.fromHtml(html2));
tv.setMovementMethod(LinkMovementMethod.getInstance());

4

如果使用基于XML的TextView,则仅需满足以下两项要求:

  1. 在字符串中标识您的链接,例如“这是我的网页”。您可以将其添加到xml或代码中。

  2. 在具有TextView的xml中,添加以下内容:


android:linksClickable="true"

android:autoLink="web"

4

将CDATA添加到您的字符串资源

Strings.xml

<string name="txtCredits"><![CDATA[<a href=\"http://www.google.com\">Google</a>]]></string>

3

我使用自动链接对文本进行“自动下划线”,但只是对其进行了“ onClick”管理。(我自己遇到了这个问题)

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="10dp"
            android:textSize="18dp"
            android:autoLink="all"
            android:text="@string/twitter"
            android:onClick="twitter"/>

public void twitter (View view)
    {
        try
        {
            Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://twitter.com/onaclovtech"));
            startActivity(browserIntent);

        }
        finally
        {
        }
    }

不需要任何权限,因为您可以将意图传递给管理那些资源的应用程序(IE浏览器)。

这就是对我有用的。祝好运。


您并不是要创建一个可点击的链接,而是要使整个TextView可点击...这不是问题。
clauziere

同意,但有时可行的解决方法是同一回事。很显然,在写出最受欢迎的答案之后的5年,这仍然是一个问题,六个月之内,我遇到了同样的问题,但最终得到了一个不同但可行的解决方案。
onaclov2000 '16

2

只是浪费了很多时间弄清楚您必须使用getText(R.string.whatever)而不是getString(R.string.whatever)...

无论如何,这就是我的工作方式。在同一文本视图中也具有多个超链接。

    TextView termsTextView = (TextView) getActivity().findViewById(R.id.termsTextView);
    termsTextView.append("By registering your account, you agree to our ");
    termsTextView.append(getText(R.string.terms_of_service));
    termsTextView.append(", ");
    termsTextView.append(getText(R.string.fees));
    termsTextView.append(", and the ");
    termsTextView.append(getText(R.string.stripe_connected_account_agreement));

    termsTextView.setMovementMethod(LinkMovementMethod.getInstance());



            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/termsTextView"/>

字符串示例

    <string name="stripe_connected_account_agreement"><a href="https://stripe.com/connect/account-terms">Stripe Connected Account Agreement</a></string>

这更加简单明了并且易于使用。因此,我有多个链接与自定义文本一起在动态添加的TextView中工作。这需要尽可能多的投票。我对Spanned字符串,自定义TextViews和HtmlCompat.fromHtml方法不屑一顾。非常感谢@ luca992。
Parth Patel
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.