TextView
文本控件
顯示富文本(URL、不同大小、字體、顏色的文本)
在TextView中預(yù)定義了一些類似HTML標簽(不區(qū)分大小寫),通過這些標簽,我們可以使TextView控件顯示不同的顏色、大小、字體的文字。
常見的標簽如下:
| <font> | 設(shè)置顏色和字體 ,只支持color和face兩個屬性 |
| <big> | 大號字體 |
| <small> | 小號字體 |
| <i> | 斜體 |
| <b> | 粗體 |
| <tt> | 等寬字體(Monospace) |
| <br> | 換行(行與行之間沒有空行),相當于\n |
| <p> | 換行(行與行之間有空行),相當于\n\n. 對于帶有標簽的文本,直接使\n無法換行,只能使用<br> 或者<p> |
| <a> | 超鏈接 |
| <img> | 插入圖像,只有一個src屬性 |
雖然和HTML標簽類似,但是并不具備HTML標簽的全部功能。
不能將帶有標簽的字符串直接使用TextView.setText()的方法進行設(shè)置,需要使用Html.fromHtml()將帶有標簽的字符串轉(zhuǎn)換成CharSequence對象,然后再使用TextView.setText()方法進行設(shè)置。
如果想要在顯示的文本中將URL、Email、電話號碼等特殊內(nèi)容高亮顯示,并在單擊的時候觸發(fā)相關(guān)的動作(URL會調(diào)用瀏覽器顯示網(wǎng)址,電話號碼會在撥號界面顯示電話號),可以通過設(shè)置<TextView>標簽的android.autoLink屬性來實現(xiàn)
| none | 不匹配任何鏈接(默認值) |
| web | 匹配Web網(wǎng)址 |
| 匹配Email | |
| phone | 匹配電話號碼 |
| map | 匹配映射地址 |
| all | 匹配所有的連接 |
Demo:
android:autoLink=”all”
注意
在調(diào)用setText方法設(shè)置文本完成后,還需要調(diào)用 setMovementMethod方法設(shè)置一個MovementMethod對象。 由于本例中<a>標簽是鏈接,因此,需要使用LinkMovementMethod.getInstance()方法獲得MovementMethod對象,該對象可以使單擊瀏覽器時顯示指定的網(wǎng)頁,如果不設(shè)置MovementMethod對象,雖然可以正常顯示a標簽指定的鏈接,但是單擊鏈接任何反應(yīng)。
在TextView中顯示 表情圖像和文字
<img>標簽可以實現(xiàn)。img標簽只有一個src屬性,該屬性原則上應(yīng)該指向一個圖像地址或可以找到某個圖像資源的唯一標識,但是系統(tǒng)并不會直接根據(jù)src屬性所指的值自動獲取和顯示圖像,需要開發(fā)人員解析。 解析src屬性值的工作需要在ImageGetter對象的getDrawable方法中完成。
ImageGetter是個接口。使用過Html.fromHtml方法的如下重載形式會比較熟悉它。
public static Spanned fromHtml(String source,ImageGetter imageGetter ,TagHandler tagHandler);fromHtml方法有如下三個參數(shù):
- source:包含Html標簽的字符串
- imageGetter:ImageGetter對象。當系統(tǒng)解析到img標簽時就是調(diào)用ImageGetter對象的getDrawable方法,并將src屬性傳入getDrawable方法中。至于src屬性值的具體含義,就要在getDrawable方法中確定了。 getDrawable方法返回的是一個Drawable對象。我們可以從res/drawable資源、SD卡或者網(wǎng)絡(luò)獲得資源,并封裝成Drawable對象。
- tagHandler:TagHandler對象,這個參數(shù)使用的并不多。當系統(tǒng)處理每一個標簽的時候都會調(diào)用該對象的handleTag方法,如果不是用該參數(shù),可以設(shè)置為null.
Demo: 5張圖片,存放在res/drawable文件夾下,在一個TextView中以不同的大小顯示這5張圖片,并在其中插入相應(yīng)的文字。
由于無法直接使用文件名來引用res/drawable中的圖像資源,我們使用反射技術(shù)從R.drawable類中通過圖像資源名稱獲取對應(yīng)的圖像資源ID,實現(xiàn)的原理就是R.drawable類中的相應(yīng)的資源ID變量名就是圖像文件的文件名。
public class MultTextPicAct extends Activity {private TextView tv_textAndPic;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.activity_mult_text_pic);initView();}/*** 初始化視圖*/private void initView() {// 組件初始化tv_textAndPic = (TextView) findViewById(R.id.id_tv_textAndPic);tv_textAndPic.setTextSize(20f);tv_textAndPic.setBackgroundColor(Color.WHITE);// 定義圖文混編String html = "圖片1<img src='flag_mark_blue'/>圖片2<img src='flag_mark_gray'/><p>";html += "圖片3<img src='tag_blue'/><br>";html += "圖片4<a href='http://www.baidu.com'><img src='tag_orange'/></a><p>";html += "圖片5<img src='tag_red'/>";//使用Html.fromHtml()轉(zhuǎn)換包含Html標簽的文本,需要指定第二個參數(shù)CharSequence charSequence = Html.fromHtml(html, new Html.ImageGetter() {@Overridepublic Drawable getDrawable(String source) {// 裝載圖像資源Drawable drawable = getResources().getDrawable(getResourceId(source));// 第三個圖片按50%等比壓縮 ,其余按原大小顯示if ("tag_blue".equals(source)) {drawable.setBounds(0, 0, drawable.getIntrinsicWidth() / 2, drawable.getIntrinsicHeight() / 2);} else {drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());}return drawable;}}, null);tv_textAndPic.setText(charSequence);// 有<a>超鏈接標簽,需設(shè)置LinkMovementMethod,否則點擊無相應(yīng)tv_textAndPic.setMovementMethod(LinkMovementMethod.getInstance());}/*** 利用反射從R.drawable類中通過圖像資源名稱獲取對應(yīng)的圖像資源ID** @param name 表示res/drawable中的圖像文件名(不含擴展名)* @return 圖像資源ID*/private int getResourceId(String name) {try {// 根據(jù)資源的ID變量名(也就是圖像資源的文件名),獲得Field字段Field field = R.drawable.class.getField(name);// 取得并返回資源ID(靜態(tài)變量)的值return Integer.valueOf(field.get(null).toString());} catch (NoSuchFieldException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}return 0;} }注意:在getDrawable方法中獲取到圖像資源的drawable對象后,必須使用Drawable.setBounds方法設(shè)置圖像的顯示區(qū)域,否則顯示區(qū)域的面積為0,也就不會在TextView中顯示圖像了。其中第三個圖像等比縮小了50%,顯示效果如下
單擊鏈接彈出Activity
我們知道通過<a>標簽以及TextView自動識別的特殊文本(網(wǎng)址 電話 Email等),這些都可以通過單擊操作來觸發(fā)不同的動作。雖然這些單擊動作已經(jīng)可以滿足大部分的需求了,但是如果要想在單擊鏈接的時候執(zhí)行任意的自定義的動作,就需要學習下面的內(nèi)容了。
在Android中,Span表示一段文本的效果,例如鏈接形式,圖像,帶顏色的文本等。
所有的Span類都在android.text.style包中。
Demo:
準備一個TextView,點擊跳轉(zhuǎn)到Activity。
我們使用SpannableString對象來設(shè)置Span。
SpannableString和SpannableBuilder的區(qū)別:SpannableString不允許修改文本,只允許設(shè)置Span,而SpannableBulilder既允許修改文本,也允許設(shè)置Span。
public class Jump2Activity extends Activity {private TextView tv_jump ;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.activity_jump2);initData();}/*** 點擊TextView彈出Activity*/private void initData() {tv_jump = (TextView)findViewById(R.id.id_tv_jump2Act);String text = "顯示Activity";// 將文本轉(zhuǎn)換成SpannableString對象SpannableString spannableString = new SpannableString(text);// 將text中的所有文本設(shè)置成ClickableSpan對象,并實現(xiàn)onClick方法spannableString.setSpan(new ClickableSpan() {// 在onClick方法中可以編寫單擊鏈接時要執(zhí)行的動作@Overridepublic void onClick(View widget) {startActivity(new Intent(Jump2Activity.this,JumpTerminalAct.class));}},0,text.length() , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);// 設(shè)置控件顯示內(nèi)容tv_jump.setText(spannableString);// 在點擊鏈接時凡是要有執(zhí)行的動作,都必須要設(shè)置MovementMethod對象tv_jump.setMovementMethod(LinkMovementMethod.getInstance());} }方法說明setSpan 4個參數(shù)
public void setSpan(Object what, int start, int end, int flags) {super.setSpan(what, start, end, flags);}第一個參數(shù)需要設(shè)置一個ClickableSpan對象
第二個和第三個參數(shù)表示要設(shè)置成Span的某段文本的起始位置和終止位置。
第四個參數(shù)是一個標志,在本例中設(shè)置成了Spanned.SPAN_EXCLUSIVE_EXCLUSIVE,該標志在TextView中的意義不大,單在EditText控件中表示的含義:在當前Span效果的前后輸入字符串時并不應(yīng)用Span的效果。
還有其他的幾個值:
Spanned.SPAN_EXCLUSIVE_INCLUSIVE :在Span前面輸入的字符不應(yīng)用Span的效果,后面輸入的字符應(yīng)用Span的效果
Spanned.SPAN_INCLUSIVE_INCLUSIVE:在Span前面輸入的字符應(yīng)用Span的效果,后面輸入的字符不應(yīng)用Span的效果
Spanned.SPAN_INCLUSIVE_EXCLUSIVE:在Span前后輸入的字符都應(yīng)用Span的效果。
為指定文字添加背景
從上面的例子中我們可以總結(jié)出 設(shè)置字符串中的某個子字符串的樣式(變成可單擊的鏈接、設(shè)置字體等)步驟如下:
在SDK的android.text.style有很多現(xiàn)成的Span對象,例如BackgroundColorSpan,該類的功能是設(shè)置指定字符串的背景色。
例如:
BackgroundColorSpan只能夠設(shè)置文字的背景色,為了更加的通用,自定義一個ColorSpan類,使其能夠同時設(shè)置文字顏色和背景色(android.text.style.ForegroundColorSpan可以設(shè)置文字顏色,但并沒有可以同事設(shè)置背景和文字顏色的Span類)。
如果需要處理鏈接動作,必須要繼承ClickableSpan類,本例我們只是設(shè)置文字和背景顏色,并不需要處理任何動作,因此只需要從CharacterStyle類繼承即可。事實上,ClickableSpan也是CharacterStyle的子類。
代碼如下:
import android.app.Activity; import android.graphics.Color; import android.os.Bundle; import android.text.SpannableString; import android.text.Spanned; import android.text.TextPaint; import android.text.style.BackgroundColorSpan; import android.text.style.CharacterStyle; import android.widget.TextView;import com.turing.base.R;public class AddBackgroundAct extends Activity {private TextView tv_addbBackground;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_add_background);initView();}private void initView() {tv_addbBackground = (TextView) findViewById(R.id.id_tv_addBackground);String text = "<沒有背景><黃色背景>\n\n<藍色背景,紅色文字>";SpannableString spannableString = new SpannableString(text);int start = 6;int end = 12;BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(Color.YELLOW);spannableString.setSpan(backgroundColorSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);// <藍色背景,紅色文字> (每個 “\n”算一個長度)start = 14;end = text.length();// 創(chuàng)建ColorSpanColorSpan colorSpan = new ColorSpan(Color.RED, Color.BLUE);// 將文字轉(zhuǎn)換為ColorSpan對象spannableString.setSpan(colorSpan, start,end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);tv_addbBackground.setText(spannableString);TextView tv = (TextView)findViewById(R.id.id_tv_tv2);tv.setText("一整個字符串的普通的背景設(shè)置,文字顏色設(shè)置");tv.setBackgroundColor(Color.GREEN);tv.setTextColor(Color.DKGRAY);}/*** 自定義Span類,可以同時設(shè)置文字顏色和背景色*/class ColorSpan extends CharacterStyle {private int mTextColor;private int mBackgroundColor;public ColorSpan(int mTextColor, int mBackgroundColor) {this.mTextColor = mTextColor;this.mBackgroundColor = mBackgroundColor;}// 重寫updateDrawState方法@Overridepublic void updateDrawState(TextPaint tp) {tp.bgColor = mBackgroundColor;tp.setColor(mTextColor);}} }總結(jié):
然后在TextView標簽中引用
..... android:text="@string/link_text"帶邊框的TextView
兩種方式:
通過第一中方式實現(xiàn):
public class BorderTextView extends TextView {public BorderTextView(Context context, AttributeSet attrs) {super(context, attrs);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);Paint paint = new Paint();// 設(shè)置所繪制的邊框顏色為黑色paint.setColor(Color.BLACK);// 繪制上邊框canvas.drawLine(0, 0, this.getWidth() - 1, 0, paint);// 繪制左邊框canvas.drawLine(0, 0, 0, this.getHeight() - 1, paint);// 繪制右邊框canvas.drawLine(this.getWidth() - 1, 0, this.getWidth() - 1, this.getHeight() - 1, paint);// 繪制下邊框canvas.drawLine(0, this.getHeight() - 1, this.getWidth() - 1, this.getHeight() - 1, paint);} }XML:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><com.turing.base.activity.textViewAct.BorderTextView android:id="@+id/id_tv_borderTV"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="10dp"android:padding="10dp"android:gravity="center"android:text="自定義TextView繪制邊框"/></RelativeLayout>設(shè)置行間距
如果TextView控件中顯示了多行文本,會有一個默認的行間距。
如果要改默認的行間距,三種方法:
android:lineSpacingExtra設(shè)置精確的行間距,例如
android:lineSpacingExtra="20dp"
android:lineSpacingMultiplier 屬性設(shè)置的是默認行間距的倍數(shù)。
如果同時設(shè)置了這兩個屬性,以較大行間距為準。
setSpacing 方法:
/*** Sets line spacing for this TextView. Each line will have its height* multiplied by <code>mult</code> and have <code>add</code> added to it.** @attr ref android.R.styleable#TextView_lineSpacingExtra* @attr ref android.R.styleable#TextView_lineSpacingMultiplier*/public void setLineSpacing(float add, float mult) {if (mSpacingAdd != add || mSpacingMult != mult) {mSpacingAdd = add;mSpacingMult = mult;if (mLayout != null) {nullLayouts();requestLayout();invalidate();}}}第一個參數(shù)相當于 android:lineSpacingExtra屬性,第二個參數(shù)相當于android:lineSpaceingMultiplier屬性。系統(tǒng)會采用哪個參數(shù)作為最終的行間距,取決于哪個參數(shù)值所表示的行間距大了。
在未顯示完的文本后面加省略號(…)
當文本內(nèi)容太多的時候,控件一行顯示不開的時候,系統(tǒng)默認的會在最后顯示一個省略號(…)
通過android:ellipsize屬性可以設(shè)置省略號的位置,當屬性值為none的時候則不顯示省略號,默認在對后面加省略號。
需要設(shè)置 android:singleLine=”true”
代碼設(shè)置如下:
textView.setEllipsize(TextUtils.TruncateAt.END);xml報文設(shè)置:
<?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:background="#000"android:orientation="vertical"><TextView android:id="@+id/id_tv_ignore1"android:layout_width="150dp"android:layout_height="wrap_content"android:background="#FFF"android:ellipsize="start"android:singleLine="true"android:layout_margin="10dp"android:text="維基百科的目標是建立擁有人類全部知識的百科全書" /><TextView android:id="@+id/id_tv_ignore2"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#FFF"android:ellipsize="middle"android:singleLine="true"android:layout_margin="10dp"android:text="維基百科的目標是建立擁有人類全部知識的百科全書dddddddddddddddddddddd" /><TextView android:id="@+id/id_tv_ignore3"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#FFF"android:ellipsize="end"android:singleLine="true"android:layout_margin="10dp"android:text="維基百科的目標是建立擁有人類全部知識的百科全書ddddddddddddddddddd" /></LinearLayout>用TextView實現(xiàn)走馬燈的效果
android:focusableInTouchMode=”true”)
android:marqueeRepeatLimit=“marquee_forever”或者是大于0的整數(shù),marquee_forever表示永遠循環(huán)顯示。
<?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:background="#000"><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="#FFF"android:ellipsize="marquee"android:focusable="true"android:focusableInTouchMode="true"android:marqueeRepeatLimit="marquee_forever"android:singleLine="true"android:text="李克勤(Hacken Lee),生于香港,籍貫廣東新會崖西,中國香港歌手,演員,主持人" /></LinearLayout>垂直滾動TextView中的文本(讓TextView出現(xiàn)滾動條)
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#000"><TextView android:id="@+id/id_tv_scroll"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#FFF"android:singleLine="false"android:maxLines="4"android:scrollbars="vertical"android:scrollbarStyle="outsideOverlay"android:scrollbarFadeDuration="2000"android:padding="10dp"android:text="周杰倫, 生于中華民國臺北縣林口鄉(xiāng),是臺灣著名國語流行音樂男歌手、演員、導演及音樂創(chuàng)作人。 周杰倫于2000年正式出道并發(fā)行其個人首張同名國語專輯《Jay》,翌年憑借該張專輯獲得第十二屆臺灣金曲獎“最佳流行音樂演唱專輯獎”ddddddddddddddddddddddddddddddddddddddddddddddd。"/></RelativeLayout> public class ScrollTextViewAct extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_scroll_text_view);TextView textView = (TextView) findViewById(R.id.id_tv_scroll);textView.setMovementMethod(ScrollingMovementMethod.getInstance());} }android:scrollbars=”vertical” : 垂直滾動必須為vertical
android:scrollbarStyle=”outsideOverlay” :滾動條在文字的右側(cè)顯示。如果insideOVerlay滾動條會在右側(cè)文字上顯示(會覆蓋文字的一部分)。
android:scrollbarFadeDuration=”2000” 滾動條從出現(xiàn)到消失(以漸變的方式)的時間,單位是毫秒
總結(jié)
- 上一篇: Android常见XML属性解析
- 下一篇: EidtText