开发者社区> 范大脚脚> 正文

TextView高级

简介:
+关注继续查看
前言

  开门见山,这一篇博客主要讲一下在Android开发中,UI控件TextView的一些使用方式,并且通过四个例子实现一般项目中需要的效果来讲解TextView的使用。并且在之后的一段时间之内,都会讲解关于AndroidUI控件的开发。

TextView

  之前讲解Android布局的时候,就已经说明,所有Layout都是View的子类或者间接子类。而TextView也一样,是View的直接子类。它是一个文本显示控件,提供了基本的显示文本的功能,并且是大部分UI控件的父类,因为大部分UI控件都需要展示信息。

  如果仅仅是展示文本,那么TextView的作用就太小了,所以它还预定义了一些类似于HTML的标签,通过这些标签可以使TextView控件显示不同的颜色、大小、字体、图片、链接。这些HTML标签都需要android.text.Html类的支持,但是并不包括所有的HTML标签。

  常用的可以再TextView中设定的标签有:

    <font>:设置颜色和字体。
    <big>:设置字体大号
    <small>:设置字体小号
    <i><b>:斜体粗体
    <a>:连接网址
    <img>:图片

  使用这些标签可以用Html.fromHtml方法将这些标签的字符串转换成CharSequence接口,然后在TextView.setText()中进行设置。如果需要响应设置的HTML标签进行响应,需要设置TextView.setMovementMethod(LinkMovementMethod.getInstance())。

  CharSequence为接口类型,大家可能对其有点陌生,但是它的子类肯定会让大家有熟悉的感觉,String、StringBuffer、StringBuilder、SpannableString、SpannableStringBuilder都是其子类,它包括了字符串的所有类,因为面向对象的多态性,在这里把他理解成字符串类的抽象即可。

  除了使用HTML标签的方式设定显示文本中的URL地址、邮箱地址、电话等产生超链接出发相应的服务,可以使用android:autoLink属性来设置,以下是android:autoLink属性的介绍:

    None:默认的,不匹配任何连接。
    web:网址。
    email:邮箱。
    phone:电话号码。
    map:匹配映射网址。
    all:匹配所有连接。

显示富文本

  讲了这么多,通过第一个例子来讲解一下TextView使用HTML标签设定样式和通过autoLink属性来设置超链接效果,在XML布局文件中定义两个TextView,分别展示HTML标签和autoLink属性的使用。
复制代码

textviewdemo.xml

复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:padding="20sp" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:autoLink="all"
        android:padding="20sp"
        android:textSize="20sp" />

</LinearLayout>
复制代码

MainActivity

复制代码
package com.example.textview0;

import android.app.Activity;
import android.os.Bundle;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.widget.TextView;

public class MainActivity extends Activity {
    private TextView textView1, textView2;

    public MainActivity() {
        // TODO Auto-generated constructor stub
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.textviewdemo);
        // 通过Id获得两个TextView控件
        textView1 = (TextView) findViewById(R.id.textView1);
        textView2 = (TextView) findViewById(R.id.textView2);
        // 设置需要显示的字符串
        String html = "<font color =’red’>Hello android</font><br/>";
        html += "<font color=’#0000ff’><big><i>Hello android</i></big></font><p>";
        html += "<big><a href=’http://www.baidu.com’>百度</a></big>";
        // 使用Html.fromHtml,把含HTML标签的字符串转换成可显示的文本样式
        CharSequence charSequence = Html.fromHtml(html);
        // 通过setText给TextView赋值
        textView1.setText(charSequence);
        // 设定一个点击的响应
        textView1.setMovementMethod(LinkMovementMethod.getInstance());
        String text = "我的URL:http://www.cnblogs.com/plokmju/n";
        text += "我的email:plokmju@sina.comn";
        text += "我的电话:+010-12345678";
        // 因为textView2中有autoLink="all“的属性设定,所以会自动识别对应的连接,点击出发对应的Android程序
        textView2.setText(text);
    }
}
复制代码

 显示效果:

复制代码
TextView显示图片

  第二个例子讲解一下在TextView中显示图片的例子,依然是使用HTML标签的方式定义样式,但是使用的是Html.fromHtml()的另外一个重载的静态方法,可以设定<img>标签中的图像资源。
  static Spanned fromHtml(String source,Html.ImageGetter imageGetter,Html.TagHandler tagHandler)
  对于这个方法,在imageGetter参数中设定<img>标签中的图像资源文件,tagHandler主要是为了处理Html类无法识别的html标签的情况,一般不会用上,传值为null即可。
复制代码

 

复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textImg"
        android:layout_width="fill_parent"
        android:layout_height="match_parent"
        android:layout_margin="10dp" />

</LinearLayout>
复制代码
复制代码
package com.example.textview0;
import java.lang.reflect.Field;
import android.R.color;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.Html;
import android.text.Html.ImageGetter;
import android.text.method.LinkMovementMethod;
import android.widget.TextView;

public class MainActivity extends Activity {
    private TextView textViewImg;

    public MainActivity() {
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.textviewdemo);

        textViewImg = (TextView) findViewById(R.id.textImg);
        textViewImg.setTextColor(color.white);
        textViewImg.setBackgroundColor(color.black);
        textViewImg.setTextSize(22);
        // 设定HTML标签样式,图片3为一个超链接标签a
        String html = "图像1<img src='image1'/>图像2<img src='image2'/>";
        html += "图像3<a href='http://www,baidu.com'><img src='image2'/></a>";
        // fromHtml中ImageGetter选择html中<img>的图片资源
        CharSequence cs = Html.fromHtml(html, new ImageGetter() {

            public Drawable getDrawable(String source) {
                // source为html字符串中定义的<img>中的src的内容
                // 返回值Drawable就是对应的<img>显示的图片资源
                Drawable draw = null;
                if (source.equals("image1")) {
                    draw = getResources().getDrawable(R.drawable.image1);
                    draw.setBounds(0, 0, draw.getIntrinsicWidth(),
                            draw.getIntrinsicHeight());
                } else if (source.equals("image2")) {
                    // 设定image2尺寸等比缩小
                    draw = getResources().getDrawable(R.drawable.image2);
                    draw.setBounds(0, 0, draw.getIntrinsicWidth() / 2,
                            draw.getIntrinsicHeight() / 2);
                } else {
                    // 使用反射会更简便,无需知道src与资源Id的对应关系
                    draw = getResources().getDrawable(getResourceId(source));
                    draw.setBounds(0, 0, draw.getIntrinsicWidth(),
                            draw.getIntrinsicHeight());
                }
                return draw;
            }
        }, null);
        textViewImg.setText(cs);
        textViewImg.setMovementMethod(LinkMovementMethod.getInstance());
    }

    public int getResourceId(String source) {
        try {
            // 使用反射机制,通过属性名称,得到其内的值
            Field field = R.drawable.class.getField(source);
            return Integer.parseInt(field.get(null).toString());
        } catch (Exception e) {
            // TODO: handle exception
        }
        return 0;
    }
}
复制代码

 效果截图,其中第三个图片点击会触发浏览器访问百度网址:

复制代码
在TextView增加Click事件
  第三个例子在TextView添加点击事件,导航到其他的Activity中。使用SpannableString.setSpan()设定那一段文本需要相应点击事件。与之类似的还有SpannableBuilder对象,他们的关系和String与StringBuilder一样。
  void setSpan(Object what,int start,int end,int flags)
  在what参数中传递一个抽象类ClickableSpan,需要实现其onClick()方法,此为指定文本的点击相应时间。start和end分别指定需要响应onClick()方法的文本开始与结束。flags设定一个标识,确定使用什么方式选择文本块,一般使用Spanned接口下的SPAN_EXCLUSIVE_EXCLUSIVE对其进行赋值,表示遵循设定的开始于结束位置的文本块。
复制代码
复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <TextView
        android:id="@+id/clickTextView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:textSize="30dp" />
</LinearLayout>
复制代码
复制代码
package com.example.textview0;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends Activity {
    private TextView clickTextView1, clickTextView2;

    public MainActivity() {
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.textviewdemo);
        clickTextView1 = (TextView) this.findViewById(R.id.clickTextView1);
        String text1 = "显示Activity1";
        // 使用SpannableString存放字符串
        SpannableString spannableString = new SpannableString(text1);
        // 通过setSpan设定文本块响应的点击事件
        // 此处只设定文本的索引为2开始的文本块:Activity1
        spannableString.setSpan(new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                // 导航到一个新的 Activity1中
                Intent intent = new Intent(MainActivity.this, Activity1.class);
                startActivity(intent);
            }
        }, 2, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        // 对TextView文本进行赋值
        clickTextView1.setText(spannableString);
        // 设置点击响应
        clickTextView1.setMovementMethod(LinkMovementMethod.getInstance());
    }
}
复制代码

效果图,从图中可以看出只有点击setSpan中设定的代码块才可以触发点击事件:

复制代码
跑马灯效果

  说到文本显示,最常见的效果就是跑马灯效果,这里以一个例子展示跑马灯的效果,基本无需使用Java代码,在布局文件中设定各项属性就已经可以实现这个效果了。

  在看代码前,先讲解一下等下会碰到的属性:

    android:elipsize: 如果文本长度大于TextView的显示长度,则隐藏那一部分,可赋值为:none(不隐藏)、start(隐藏开始)、middle(隐藏中间)、end(隐藏结束)、marquee(滚动效果)。
    android:marqueRepeatLimit:设定需要重复动画的次数,传递一个int值,-1为无限循环。
    android:focusable:是否允许获得焦点,传递一个bool值。
    android:focusableInTouchMode:是否在获得焦点时对控件有联系,传递一个bool值。

  介绍属性后,直接看代码吧,XML布局文件runlamp_layout.xml代码:
复制代码

 

复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <TextView 
        android:id="@+id/tvRunLamp" android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:singleLine="true"
        android:ellipsize="marquee"
        android:marqueeRepeatLimit="marquee_forever"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:background="#FFF"
        android:textColor="#000"
        android:textSize="20dp" 
        android:layout_margin="10dp"
        android:padding="10dp"/>
</LinearLayout>
复制代码
复制代码
package cn.bgxt.textviewdemo;

import android.app.Activity;
import android.os.Bundle;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.widget.TextView;

public class RunLampActivity extends Activity {

    private TextView tvRunLamp;

    public RunLampActivity() {
        // TODO Auto-generated constructor stub
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.runlamp_layout);

        tvRunLamp = (TextView) findViewById(R.id.tvRunLamp);
        String html = "之前讲解Android布局的时候,就已经说明,所有<a href='http://www.cnblogs.com/plokmju/p/androidUI_Layout.html'>Layout</a>都是View的子类或者间接子类。而TextView也一样,是View的直接子类。它是一个文本显示控件,提供了基本的显示文本的功能,并且是大部分UI控件的父类,因为大部分UI控件都需要展示信息。";
        CharSequence cs = Html.fromHtml(html);
        tvRunLamp.setText(cs);
        //因为文本中设定了一个<a>标签,这里设置响应。
        tvRunLamp.setMovementMethod(LinkMovementMethod.getInstance());
    }
}
复制代码

运行效果图,是一个滚动的效果:

  示例源码下载

 

总结

  在此就说明了Android中TextView,并且以例子的方式说明了一些常用效果的实现。因为TextView是大部分UI控件的父类,所以其内的一些属性对于其他UI控件都是通用的,可以有借鉴的地方。


本文转自农夫山泉别墅博客园博客,原文链接:http://www.cnblogs.com/yaowen/p/5442380.html,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
23548 0
阿里云服务器ECS远程登录用户名密码查询方法
阿里云服务器ECS远程连接登录输入用户名和密码,阿里云没有默认密码,如果购买时没设置需要先重置实例密码,Windows用户名是administrator,Linux账号是root,阿小云来详细说下阿里云服务器远程登录连接用户名和密码查询方法
22283 0
如何设置阿里云服务器安全组?阿里云安全组规则详细解说
阿里云安全组设置详细图文教程(收藏起来) 阿里云服务器安全组设置规则分享,阿里云服务器安全组如何放行端口设置教程。阿里云会要求客户设置安全组,如果不设置,阿里云会指定默认的安全组。那么,这个安全组是什么呢?顾名思义,就是为了服务器安全设置的。安全组其实就是一个虚拟的防火墙,可以让用户从端口、IP的维度来筛选对应服务器的访问者,从而形成一个云上的安全域。
19269 0
使用SSH远程登录阿里云ECS服务器
远程连接服务器以及配置环境
14710 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,云吞铺子总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系统盘、创建快照、配置安全组等操作如何登录ECS云服务器控制台? 1、先登录到阿里云ECS服务器控制台 2、点击顶部的“控制台” 3、通过左侧栏,切换到“云服务器ECS”即可,如下图所示 通过ECS控制台的远程连接来登录到云服务器 阿里云ECS云服务器自带远程连接功能,使用该功能可以登录到云服务器,简单且方便,如下图:点击“远程连接”,第一次连接会自动生成6位数字密码,输入密码即可登录到云服务器上。
36382 0
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
15950 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
14885 0
+关注
3656
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载