Android–UI之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属性的使用。

XML布局文件textviewdemo.xml代码:

复制代码
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical" >    
 6     <TextView 
 7         android:id="@+id/textView1"
 8         android:layout_width="fill_parent"
 9         android:layout_height="wrap_content"
10         android:padding="20sp"
11         />
12     <TextView 
13         android:id="@+id/textView2"
14         android:layout_width="fill_parent"
15         android:layout_height="wrap_content"
16         android:padding="20sp"
17         android:autoLink="all"
18         android:textSize="20sp"
19         />
20 </LinearLayout>
复制代码

Activity文件textViewDemoActivity.java代码:

复制代码
 1 package cn.bgxt.textviewdemo;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 import android.text.Html;
 6 import android.text.method.LinkMovementMethod;
 7 import android.widget.TextView;
 8 
 9 public class textViewDemoActivity extends Activity {
10 
11     private TextView textView1,textView2;
12     public textViewDemoActivity() {
13         // TODO Auto-generated constructor stub
14     }    
15     @Override
16     protected void onCreate(Bundle savedInstanceState) {
17         // TODO Auto-generated method stub
18         super.onCreate(savedInstanceState);
19         setContentView(R.layout.textviewdemo);
20         //通过Id获得两个TextView控件
21         textView1=(TextView)findViewById(R.id.textView1);
22         textView2=(TextView)findViewById(R.id.textView2);
23         
24         //设置需要显示的字符串
25         String html="<font color ='red'>Hello android</font><br/>";
26         html+="<font color='#0000ff'><big><i>Hello android</i></big></font><p>";
27         html+="<big><a href='http://www.baidu.com'>百度</a></big>";
28         //使用Html.fromHtml,把含HTML标签的字符串转换成可显示的文本样式
29         CharSequence charSequence=Html.fromHtml(html);
30         //通过setText给TextView赋值
31         textView1.setText(charSequence);
32         //设定一个点击的响应
33         textView1.setMovementMethod(LinkMovementMethod.getInstance());
34         
35         String text="我的URL:http://www.cnblogs.com/plokmju/\n";
36         text+="我的email:plokmju@sina.com\n";
37         text+="我的电话:+86 010-12345678";
38         //因为textView2中有autoLink=”all“的属性设定,所以会自动识别对应的连接,点击出发对应的Android程序
39         textView2.setText(text);
40     }
41 
42 }
复制代码

显示效果:

 

TextView显示图片

第二个例子讲解一下在TextView中显示图片的例子,依然是使用HTML标签的方式定义样式,但是使用的是Html.fromHtml()的另外一个重载的静态方法,可以设定<img>标签中的图像资源。

static Spanned fromHtml(String source,Html.ImageGetter imageGetter,Html.TagHandler tagHandler)

对于这个方法,在imageGetter参数中设定<img>标签中的图像资源文件,tagHandler主要是为了处理Html类无法识别的html标签的情况,一般不会用上,传值为null即可。

布局XML文件textvideforimg.xml代码:

复制代码
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical" >
 6     <TextView
 7         android:id="@+id/textImg"
 8         android:layout_width="fill_parent"
 9         android:layout_height="match_parent"
10         android:layout_margin="10dp" />
11 </LinearLayout>
复制代码

Activity文件textviewForImgActivity.java代码:

复制代码
 1 package cn.bgxt.textviewdemo;
 2 
 3 import java.lang.reflect.Field;
 4 
 5 import android.R.color;
 6 import android.app.Activity;
 7 import android.graphics.drawable.Drawable;
 8 import android.os.Bundle;
 9 import android.text.Html;
10 import android.text.Html.ImageGetter;
11 import android.text.method.LinkMovementMethod;
12 import android.widget.TextView;
13 
14 public class textviewForImgActivity extends Activity  {
15 
16     private TextView textViewImg;
17     public textviewForImgActivity() {
18         // TODO Auto-generated constructor stub
19     }
20     
21     @Override
22     protected void onCreate(Bundle savedInstanceState) {
23         // TODO Auto-generated method stub
24         super.onCreate(savedInstanceState);
25         setContentView(R.layout.textvideforimg);
26         
27         textViewImg=(TextView)findViewById(R.id.textImg);
28         textViewImg.setTextColor(color.white);
29         textViewImg.setBackgroundColor(color.black);
30         textViewImg.setTextSize(20);
31         //设定HTML标签样式,图片3为一个超链接标签a
32         String html="图像1<img src='image1'/>图像2<img src='image2'/>\n";
33         html+="图像3<a href='http://www,baidu.com'><img src='image3'/></a>";
34         //fromHtml中ImageGetter选择html中<img>的图片资源
35         CharSequence cs=Html.fromHtml(html, new ImageGetter() {
36             
37             public Drawable getDrawable(String source) {
38                 //source为html字符串中定义的<img>中的src的内容
39                 //返回值Drawable就是对应的<img>显示的图片资源
40                 Drawable draw=null;
41                 if(source.equals("image1"))
42                 {
43                     draw=getResources().getDrawable(R.drawable.image1);
44                     draw.setBounds(0, 0, draw.getIntrinsicWidth(), draw.getIntrinsicHeight());
45                 }
46                 else if(source.equals("image2"))
47                 {
48                     //设定image2尺寸等比缩小
49                     draw=getResources().getDrawable(R.drawable.image2);
50                     draw.setBounds(0, 0, draw.getIntrinsicWidth()/2, draw.getIntrinsicHeight()/2);
51                 }
52                 else
53                 {
54                     //使用反射会更简便,无需知道src与资源Id的对应关系
55                     draw=getResources().getDrawable(getResourceId(source));
56                     draw.setBounds(0, 0, draw.getIntrinsicWidth(), draw.getIntrinsicHeight());
57                 }
58                 return draw;
59             }
60         }, null);
61         textViewImg.setText(cs);
62         textViewImg.setMovementMethod(LinkMovementMethod.getInstance());
63     }
64     
65     public int getResourceId(String source)
66     {
67         try {
68             //使用反射机制,通过属性名称,得到其内的值
69             Field field=R.drawable.class.getField(source);
70             return Integer.parseInt(field.get(null).toString());
71         } catch (Exception e) {
72             // TODO: handle exception
73         }
74         return 0;
75     }
76     
77 }
复制代码

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

 

在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对其进行赋值,表示遵循设定的开始于结束位置的文本块。

布局文件activityclick.xml的代码:

复制代码
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical" >
 6     <TextView
 7         android:id="@+id/clickTextView1"
 8         android:textSize="30dp"
 9         android:layout_marginTop="30dp"
10         android:layout_width="match_parent"
11         android:layout_height="wrap_content" />
12     <TextView
13          android:textSize="30dp"
14          android:layout_marginTop="30dp"
15         android:id="@+id/clickTextView2"
16         android:layout_width="match_parent"
17         android:layout_height="wrap_content" />
18 </LinearLayout>
复制代码

Activity文件TextViewOnClickActivity.java的代码:

复制代码
 1 package cn.bgxt.textviewdemo;
 2 
 3 import android.app.Activity;
 4 import android.content.Intent;
 5 import android.os.Bundle;
 6 import android.text.SpannableString;
 7 import android.text.Spanned;
 8 import android.text.method.LinkMovementMethod;
 9 import android.text.style.ClickableSpan;
10 import android.view.View;
11 import android.widget.TextView;
12 
13 public class TextViewOnClickActivity extends Activity {
14 
15     private TextView clickTextView1,clickTextView2;
16     
17     public TextViewOnClickActivity() {
18     }
19 
20     @Override
21     protected void onCreate(Bundle savedInstanceState) {
22         super.onCreate(savedInstanceState);
23         setContentView(R.layout.activityclick);
24         
25         clickTextView1=(TextView)this.findViewById(R.id.clickTextView1);
26         clickTextView2=(TextView)this.findViewById(R.id.clickTextView2);
27         String text1="显示Activity1";
28         String text2="显示Activity2";
29         //使用SpannableString存放字符串
30         SpannableString spannableString=new SpannableString(text1);
31         SpannableString spannableString2=new SpannableString(text2);
32         //通过setSpan设定文本块响应的点击事件
33         //此处只设定文本的索引为2开始的文本块:Activity1
34         spannableString.setSpan(new ClickableSpan() {            
35             @Override
36             public void onClick(View widget) {
37                 //导航到一个新的 Activity1中
38                 Intent intent=new Intent(TextViewOnClickActivity.this,Activity1.class);
39                 startActivity(intent);
40             }
41         }, 2, text1.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
42         
43         spannableString2.setSpan(new ClickableSpan() {
44             
45             @Override
46             public void onClick(View widget) {
47                 // TODO Auto-generated method stub
48                 Intent intent=new Intent(TextViewOnClickActivity.this,Activity2.class);
49                 startActivity(intent);
50             }
51         }, 2, text1.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
52         
53         //对TextView文本进行赋值
54         clickTextView1.setText(spannableString);
55         //设置点击响应
56         clickTextView1.setMovementMethod(LinkMovementMethod.getInstance());
57         clickTextView2.setText(spannableString2);
58         clickTextView2.setMovementMethod(LinkMovementMethod.getInstance());
59         
60         
61         
62     }
63 }
复制代码

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

 

跑马灯效果

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

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

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

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

 

复制代码
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical" >
 6     
 7     <TextView 
 8         android:id="@+id/tvRunLamp" android:layout_width="fill_parent"
 9         android:layout_height="wrap_content"
10         android:singleLine="true"
11         android:ellipsize="marquee"
12         android:marqueeRepeatLimit="marquee_forever"
13         android:focusable="true"
14         android:focusableInTouchMode="true"
15         android:background="#FFF"
16         android:textColor="#000"
17         android:textSize="20dp" 
18         android:layout_margin="10dp"
19         android:padding="10dp"/>
20 </LinearLayout>
复制代码

Activity文件RunLampActivity.java代码:

复制代码
 1 package cn.bgxt.textviewdemo;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 import android.text.Html;
 6 import android.text.method.LinkMovementMethod;
 7 import android.widget.TextView;
 8 
 9 public class RunLampActivity extends Activity {
10 
11     private TextView tvRunLamp;
12 
13     public RunLampActivity() {
14         // TODO Auto-generated constructor stub
15     }
16 
17     @Override
18     protected void onCreate(Bundle savedInstanceState) {
19         // TODO Auto-generated method stub
20         super.onCreate(savedInstanceState);
21         setContentView(R.layout.runlamp_layout);
22 
23         tvRunLamp = (TextView) findViewById(R.id.tvRunLamp);
24         String html = "之前讲解Android布局的时候,就已经说明,所有<a href='http://www.cnblogs.com/plokmju/p/androidUI_Layout.html'>Layout</a>都是View的子类或者间接子类。而TextView也一样,是View的直接子类。它是一个文本显示控件,提供了基本的显示文本的功能,并且是大部分UI控件的父类,因为大部分UI控件都需要展示信息。";
25         CharSequence cs = Html.fromHtml(html);
26         tvRunLamp.setText(cs);
27         //因为文本中设定了一个<a>标签,这里设置响应。
28         tvRunLamp.setMovementMethod(LinkMovementMethod.getInstance());
29     }
30 }
复制代码

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

示例源码下载

 

总结

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

请支持原创,尊重原创,转载请注明出处。谢谢。

(作者:承香墨影)

本文来源:http://www.cnblogs.com/plokmju/p/Android_UI_TextView.html


如果给你带来帮助,欢迎微信或支付宝扫一扫,赞一下。