学习Google Sample 如何给TextView增加超链接

本文通过分析Google示例代码,介绍了如何在Android中为TextView添加超链接,包括通过XML资源文件设置、Java代码实现以及SpannableString的使用。讨论了自动链接属性(autoLink)、HTML标记以及CDATA的作用,并提供了不同情况下的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天上午看了如何Google的一个示例代码,学到了一些和TextView相关的知识。消灭了我无知的认为TextView就是显示字的幼稚想法,我对学到了内容简单罗列一下就开始记录:

  • 在strings.xml资源文件里面,设置斜体,加粗
  • 给strings.xml里的字符串自动添加超链接
  • 给strings.xml里的资源文件显式地添加超链接—通过< a >标记
  • 在Java代码用HTML给文字添加超链接
  • 在Java代码不用HTML给文字添加超链接

说一下,超链接不只是访问网页,也可以是一个电话号码。

先上图:
主界面

点击电话号码

下面开始代码分析


首先先贴一下sample_main.xml的布局文件吧:

<ScrollView
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:context=".MainActivity">

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:paddingBottom="@dimen/activity_vertical_margin"
            android:paddingLeft="@dimen/activity_horizontal_margin"
            android:paddingRight="@dimen/activity_horizontal_margin"
            android:paddingTop="@dimen/activity_vertical_margin">


            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/intro" />

            <!-- text_auto_linkify automatically linkifies things like URLs and phone numbers. -->
            <TextView
                android:id="@+id/text_auto_linkify"
                style="@style/LinkText"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:autoLink="all"
                android:text="@string/link_text_auto" />

            <!--
                   text_html_resource uses a string resource containing explicit anchor tags (<a>)
                   to specify links.
            -->
            <TextView
                android:id="@+id/text_html_resource"
                style="@style/LinkText"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>

            <!-- text_html_program builds the text in the Java code using HTML. -->
            <TextView
                android:id="@+id/text_html_program"
                style="@style/LinkText"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

            <!-- text_spannable builds the text in the Java code without using HTML. -->
            <TextView
                android:id="@+id/text_spannable"
                style="@style/LinkText"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </LinearLayout>
    </ScrollView>

我们看到一共有5个TextView,这五个TextView就对应布局文件里面的五段话,大家可以回去看一看(因为显示不下,第五段话只显示了一行)。因为每个TextView都有新知识,我们就一个一个的看过来:

第一个TextView

第一段话由一个换行,和一个斜体。而且从布局文件里看到它只是引用了strings.xml里面的字符串资源。我们看一下对应的字符串资源:

    <string name="intro">
    This sample illustrates how links can be added to a TextView.
    \nThis can be done either automatically by setting the <i>autoLink</i> property
    </string>

换行大家都能想到,加上\n就可以啦,斜体通过< i > XXX < /i >这样的形式,就能直接把XXX变成斜体了!


第二个TextView

第二段话就不一样了,它有斜体,而又超链接。先看看它的布局怎么写的:

            <TextView
                android:id="@+id/text_auto_linkify"
                style="@style/LinkText"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:autoLink="all"
                android:text="@string/link_text_auto" />

相比第一个,除了多了style属性,由一个新的属性 autoLink ,这个属性有什么用?

答:通过这个属性,TextView会自动识别字符串里的URL资源(网址和电话,邮箱之类的),然后自动加超链接。

我们先看看它对应的字符串资源:

<string name="link_text_auto"><b>text_auto_linkify: Various kinds
      of data that will be auto-linked.</b>
      In this text are some things that are actionable.  For instance,
      you can click on http://www.google.com and it will launch the
      web browser.  You can click on google.com too.  If you
      click on (415) 555-1212 it should dial the phone.  Or just write
      foobar@example.com for an e-mail link.  If you have a URI like
      http://www.example.com/lala/foobar@example.com you should get the
      full link not the e-mail address.  Or you can put a location
      like 1600 Amphitheatre Parkway, Mountain View, CA 94043.  To summarize:
      https://www.google.com, or 650-253-0000, somebody@example.com,
      or 9606 North MoPac Expressway, Suite 400, Austin, TX 78759.</string>

我们发现就是显示出来的内容,就是加粗部分的文字是通过嵌套< b >标记实现的。看来还是挺简单的,但还有呢!


第三个TextView

我们先看它的布局:

            <TextView
                android:id="@+id/text_html_resource"
                style="@style/LinkText"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>

我们看到它没有指定字符串和autoLink属性,那就是在代码中完成的。

Java文件的代码只有一个,MainActivity:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.sample_main);



        TextView textViewResource = (TextView) findViewById(R.id.text_html_resource);
        textViewResource.setText(
                Html.fromHtml(getResources().getString(R.string.link_text_manual)));
        textViewResource.setMovementMethod(LinkMovementMethod.getInstance());


        TextView textViewHtml = (TextView) findViewById(R.id.text_html_program);
        textViewHtml.setText(
                Html.fromHtml(
                        "<b>text_html_program: Constructed from HTML programmatically.</b>"
                                + "  Text with a <a href=\"http://www.google.com\">link</a> "
                                + "created in the Java source code using HTML."));
        textViewHtml.setMovementMethod(LinkMovementMethod.getInstance());

        SpannableString ss = new SpannableString(
                "text_spannable: Manually created spans. Click here to dial the phone.");


        ss.setSpan(new StyleSpan(Typeface.BOLD), 0, 39,
                Spanned.SPAN_INCLUSIVE_INCLUSIVE);
        ss.setSpan(new URLSpan("tel:4155551212"), 40 + 6, 40 + 10,
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        TextView textViewSpan = (TextView) findViewById(R.id.text_spannable);
        textViewSpan.setText(ss);


        textViewSpan.setMovementMethod(LinkMovementMethod.getInstance());
        // END_INCLUDE(text_spannable)
    }

}

其中对应于它的Java代码是这一段:

        TextView textViewResource = (TextView) findViewById(R.id.text_html_resource);
        textViewResource.setText(
                Html.fromHtml(getResources().getString(R.string.link_text_manual)));
        textViewResource.setMovementMethod(LinkMovementMethod.getInstance());

我们先看看它引用的资源文件:

<string name="link_text_manual"><![CDATA[<b>text_html_resource:
      Explicit links using &lt;a&gt; markup.</b>
      This has markup for a <a href="http://www.google.com">link</a> specified
      via an &lt;a&gt; tag.  Use a \"tel:\" URL
      to <a href="tel:4155551212">dial a phone number</a>.]]></string>

它是通过用< a >来标记需要添加超链接的内容,然后再用Java代码中的方法 Html.fromHtml()来给标记好的内容加上超链接。

如果你没有对它调用setMovementMethod(),那么即使添加了超链接,它也不会响应用户的输入的。

除了这个之外,我们看到它对应的字符串资源是什么鬼?” ![CDATA[]]”,“ & lt; ”, “& gt;”,恩,我查了一下

  • “ & lt; ”
  • “& gt;”

分别是XML里面预先定义好的实体,如果认真观察不难发现,它们就是<和>。

那么” ![CDATA[]]” 的意义在哪里????

标明是纯文本的,没有这个的话 < > & 字符是不能直接存入XML的,需要转义,而用这个标记则不需要转义而将这些符号存入XML文档。
可以避免未预料的特殊符号导致XML解析出错。

哦,虽然有点道理,记住就好了,就和当初 \n 代表换行是一个道理。


第四个TextView

我们先看看它的JAVA代码:

        TextView textViewHtml = (TextView) findViewById(R.id.text_html_program);
        textViewHtml.setText(
                Html.fromHtml(
                        "<b>text_html_program: Constructed from HTML programmatically.</b>"
                                + "  Text with a <a href=\"http://www.google.com\">link</a> "
                                + "created in the Java source code using HTML."));
        textViewHtml.setMovementMethod(LinkMovementMethod.getInstance());

我们看到它没有自己引用,和上面的相比,只是把引用的资源换成了自己手打的而已,那它出现在教程有什么意思呢?

对于固定的字符串资源来说,直接引用strings.xml里面定义好的资源无疑是一种更好的方法,但是一个方法只要是向我们展示如何如何给动态内容添加超链接,比如来自网络的文本。


第五个TextView

第五个画风就不一样了,它在xml布局文件里使用autoLink,也不在java代码里用Html方法,先看看它对应代码:

SpannableString ss = new SpannableString(
                "text_spannable: Manually created spans. Click here to dial the phone.");
ss.setSpan(new StyleSpan(Typeface.BOLD), 0, 39,
                Spanned.SPAN_INCLUSIVE_INCLUSIVE);
ss.setSpan(new URLSpan("tel:4155551212"), 40 + 6, 40 + 10,
        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

TextView textViewSpan = (TextView) findViewById(R.id.text_spannable);
textViewSpan.setText(ss);
textViewSpan.setMovementMethod(LinkMovementMethod.getInstance());

我们看到它是先构造好字符串,然后再设置给TextView。

开始他用了一个SpannableString,来构造固定的字符串,而SpannableString是什么呢?
Google API这么说:

This is the class for text whose content is immutable but to which markup objects can be attached and detached.

大概的意思是说,对于固定的文本,它可以实现在文本上加效果地功能。

我们看到它不仅加了加粗,还加了URL,这样就构造好了,然后和之前一样设置给TextView就可以了。关于更加详细地用法,由于不是重点,我也没有看,不过SpannableString这个可以改变字体的颜色大小粗细等很多很多属性,如果感兴趣可以搜一下,关于它的内容很多。


好了,关于如何给TextView添加超链接的就介绍到这里了。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值