Android開發之TextView進階應用程式
Android開發之TextView進階應用程式
我們平時使用TextView往往讓它作為一個顯示文字的容器,但TextView的功能並不局限於此。下面就和大家分享一下TextView的一些提示。
Android中設定文本樣式的幾種方法:
1.將android:autoLink屬性值設為true。系統會自動識別E-mail、電話、網址等特殊文本。
2.使用Html標籤,例如,、等。不要設定 android:autoLink 屬性。
3.在Java代碼中直接使用Span對象來設定文本樣式。這種方法需要將文本轉換成一個SpannableString或SpannableStringBuilder對象,然後在SpannableString或SpannableStringBuilder對象中使用setSpan方法將要設定樣式的文本轉換成相應的Span對象。
4.在字串資源中使用標籤(只支援標籤)設定可單擊的連結,不要設定android:audoLink屬性。
上面4種方法只要涉及單擊動作,就必須使用TextView.setMovementMethod方法設定相應的MovementMethod對象。
1.在TextView中顯示映像
我們瀏覽網的時候,上面的有很多圖文並茂的文章,這些文章大部分都是從伺服器的資料庫中取出並顯示在網頁上的。那麼如何在網頁上顯示圖文並茂的文章呢?有過Java Web或.NET開發經驗的人,會說用s:textfield或asp:label綁定。用它們是因為它們可以將標籤的src對應的映像地址(也是映像資源的唯一標識)直接交給瀏覽器出處理。這樣就可以將的src對應的圖片顯示出來。
那麼,在Android中如何用TextView顯示圖片呢?
在解析Html標籤來方面Android系統沒有瀏覽器那麼強大,Android系統不會直接根據src屬性說指向的的值自動擷取並顯示圖片,這一切都需要我們來幫它來完成。說白了,src屬性指的是什麼只有開發人員自己知道。開發人員需要告訴系統src屬性到底指的是什麼,然後系統才會知道怎麼做。
解析src屬性值需要ImageGetter對象的getDrawable方法來完成。ImageGetter是一個介面。使用Html.fromHtml會使這一過程變得簡單。(關於Html.fromHtml的介紹)
txtShow=(TextView)findViewById(R.id.txtShow); String htmlText="小黃人1號:" +"小黃人2號:"+"小黃人3號:"; txtShow.setText(getSpanned(htmlText)); |
/** *將Html解析成樣式文本 *@return spanned Spanned * */ private Spanned getSpanned(String htmlText) { //TODO Auto-generated method stub Spanned spanned=Html.fromHtml(htmlText,new ImageGetter() { @Override public Drawable getDrawable(String source) { //TODO Auto-generated method stub //裝在映像資源 Drawable drawable=getResources().getDrawable(getResourceId(source)); if (source.equals("http://blog.csdn.net/fengyuzhengfan/article/details/xiaohuangren1")) { //設定映像的縮放 drawable.setBounds(0, 0, 56, 56); }elseif (source.equals("http://blog.csdn.net/fengyuzhengfan/article/details/xiaohuangren2")) { //設定映像的縮放 drawable.setBounds(0, 0, 36, 36); }elseif (source.equals("http://blog.csdn.net/fengyuzhengfan/article/details/xiaohuangren3")) { //設定映像縮放到原來的75% drawable.setBounds(0, 0,(int) (drawable.getIntrinsicWidth()*0.75), (int) (drawable.getIntrinsicHeight()*0.75)); } return drawable; } },null); return spanned; } /** *利用反射技術從R.drawable類中通過映像資源檔名獲得相應映像資源的ID *@param name String映像資源名 *@return映像資源ID int * */ protectedint getResourceId(String name) { //TODO Auto-generated method stub try { //根據資源ID的變數名(也就是映像資源的檔案名稱)擷取Field對象 Field field=R.drawable.class.getField(name); //取得並返回資源ID的值 return Integer.parseInt(field.get(null).toString()); }catch (Exception e) { //TODO: handle exception } return 0; } |
2.單擊TextView中的內容開啟指定Activity
雖然TextView可以自動識別特殊文本(網址、電話號、E-mail等),並可以通過單擊觸發不同的動作。但是如果開發人員想通過單擊連結來顯示指定的組件(如Activity、Service等)那麼怎麼來實現呢?
TextView自動識別的網址、電話號、E-mail等,都是在ClickableSpan類的onClick方法中通過Action調用相應的組件來實現的。現在我們就採用類似的方法,通過自己實現onClick方法來達到自訂自訂單擊動作的目的。
/** *單擊TextView中的內容啟動指定組件 * */ privatevoid launchComponentByTextView() { //TODO Auto-generated method stub txtLink=(TextView)findViewById(R.id.txtLink); String str="單擊我啟動一個Activity"; //將文本轉換成SpannableString對象 SpannableString spannableString=new SpannableString(str); //將spannableString所有文本設定成ClickableSpan對象,並實現onClick方法 spannableString.setSpan(new ClickableSpan() { @Override publicvoid onClick(View widget) { //TODO Auto-generated method stub //啟動指定Activity Intent intent=new Intent(MainActivity.this, SecondActivity.class); startActivity(intent); } }, 0, str.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); txtLink.setText(spannableString); //在單擊連結時凡是要執行的動作,都必須設定MovementMethod對象 txtLink.setMovementMethod(LinkMovementMethod.getInstance()); } |
執行個體分析:
在本例中setSpan方法的第四個參數設定成了Spanned.SPAN_EXCLUSIVE_EXCLUSIVE,該標誌在 TextView 控制項中意義不大,但在 EditText控制項中表示在當前Span效果的前後輸入字元時並不應用Span的效果。關於SpannableString的詳細介紹大家可以參照:Android開發之SpannableString詳解。
3.為指定文本添加顏色和背景色
從前面幾個執行個體的內容可以得知設定字元中某個子字串的樣式(變成可單擊的連結、設定字型等)需要如下幾步。
(1) 將字串轉換成SpannableString或SpannableStringBuilder對象。
(2) 獲得要設定樣式的子字串在原字串中的開始位置和子字串後面的字元的位置,也就是 start和end。
(3) 建立一個Span對象(所有android.text.style包中的XxxSpan類建立的對象的統稱,Xxx表示URL、BackgroundColor等類的首碼)。
(4) 使用setSpan方法設定個Span對象,也就足說?將要設定樣式的子字串轉換成坤拙對象。
(5) 用處理完的SpannableString或SpannableStringBuilder對象設定相應的控制項(如TextView、EditText、Button等)。
在Android SDK的andrmd.text.styte包中提供很多現成的Span對象,例如’ BackgroundColorSpan類就是一個很常用的Span類,該類的功能是設定指定字串的背景色,使用方法如下:
txtSetBackgroundColor=(TextView)findViewById(R.id.txtSetBackgroundColor); String str="沒有背景|黃色背景"; //第一步將字串轉換成SpannableString對象 SpannableString spannableString=new SpannableString(str); //第二步確定設定要設定的子字串在原字串的開始位置和接收位置即start和end String subStr="黃色背景"; int start=str.indexOf(subStr); int end=start+subStr.length(); //第三步建立一個BackgroundColorSpan對象 BackgroundColorSpan backgroundColorSpan=new BackgroundColorSpan(Color.YELLOW); //第四步使用setSpan方法將指定子字串轉換成BackgroundColorSpan對象對象 spannableString.setSpan(backgroundColorSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //第五步用SpannableString對象設定TextView控制項 txtSetBackgroundColor.setText(spannableString); |
BackgroundColorSpan只能設定文字的背景色,為了更加通用,我們來自己編寫一個ColorSpan類,使其同時可以設定文字顏色和背景色(android.text.style.ForegroundColorSpan類可以設定文字顏色,但並沒有可同時設定背景和文字顏色的Span類)。在執行個體2給出了一個通過繼承ClickableSpan類來編寫自訂Span類的例子,不過這個例子需要處理連結動作,所以必須要繼承ClickableSpan類。而本例只要設定文字和背景顏色即可,並不需要處理任何動作,因此,只需要從CharacterStyle類繼承即可。實際上,ClickableSpan也是CharacterStyle的子類。可以設定文字和背景顏色的ColorSpan類的代碼如下:
/** * Describe:
* 自訂一個CharacterStyle的子類 * 用於修改文字的顏色和背景色 * @author jph * Date:2014.08.10 * */ publicclass ColorSpanextends CharacterStyle { //聲明文字的顏色和背景色 privateinttextColor,backgroundColor; /** *初始化ColorSpan類 *@param textColor 文字顏色 *@param backgroundColor文字背景色 * */ public ColorSpan(int textColor,int backgroundColor) { //TODO Auto-generated constructor stub this.textColor=textColor; this.backgroundColor=backgroundColor; } //覆蓋CharacterStyle類中的updateDrawState方法,並在該方法中設定字型顏色和背景色 @Override publicvoid updateDrawState(TextPaint tp) { //TODO Auto-generated method stub tp.bgColor=backgroundColor; tp.setColor(textColor); } } |
在ColorSpan類中實現了CharacterStyle類的updateDrawState方法。該方法在系統開始繪製要設定樣式的字串之前調用,以便修改繪製文字的屬性,例如,文字顏色、背景顏色等。其中TextPaint是Paint的子類。Paint類用於描述繪製的屬性,如畫筆的顏色、畫筆的粗細等。現在我們來同時使用BackgroundColorSpan和ColorSpan類設定文字和背景顏色,代碼如下:
txtMyColor=(TextView)findViewById(R.id.txtMyColor); ColorSpan colorSpan=new ColorSpan(Color.RED, Color.WHITE); String str="紅色字型|灰色背景"; String subStr="灰色背景"; int start=str.indexOf(subStr); int end=start+subStr.length(); SpannableString spannableString=new SpannableString(str); spannableString.setSpan(colorSpan, 0, start, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); colorSpan=new ColorSpan(Color.WHITE, Color.GRAY); spannableString.setSpan(colorSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); txtMyColor.setText(spannableString); |