前言
開門見山,這一篇博客主要講一下在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控件都是通用的,可以有借鑒的地方。
請支持原創,尊重原創,轉載請注明出處。謝謝。

