android中用Spannable在TextView中設置超連接、顏色、字體

昨晚研讀 ApiDemo 源碼至 com.example.android.apis.text.Link 類。首先,看一下其運行效果:

  要給 TextView 加上效果,方式主要有幾種:
  第一種,自動應用效果,使用 android:autolink 屬性,如:
  Java代碼
?
代碼片斷,雙擊複製
01
02
03
04
05
06
07
08
09
10
11
android:id= "@+id/text1"
 
android:layout_width= "match_parent"
 
android:layout_height= "match_parent"
 
android:autoLink= "all"
 
android:text= "@string/link_text_auto"
 
/>
  第二種,在文本中使用 標籤,如:
  Java代碼
?
代碼片斷,雙擊複製
01
02
03
04
05
06
07
text2: This is some other
 
text, with a link specified
 
via an tag. Use a \"tel:\" URL
 
to dial a phone number
  第三種,和第二種實際上是同樣的,只不過將文本改在 JAVA 代碼中,如:
  Java代碼
?
代碼片斷,雙擊複製
01
02
03
04
05
06
07
08
09
10
11
12
13
TextView t3 = (TextView) findViewById(R.id.text3);
 
t3.setText(
 
Html.fromHtml(
 
"text3: Text with a " +
 
"link " +
 
"created in the Java source code using HTML." ));
 
t3.setMovementMethod(LinkMovementMethod.getInstance());
  第四種,前面三種能夠說都是自動的,而第四種就是純「手工」的了。經過建立 SpanableString 字符串,並在之上創 建一個或多個 Span 來實現豐富的效果。例子以下:
  Java代碼
?
代碼片斷,雙擊複製
01
02
03
04
05
06
07
08
09
10
11
SpannableString ss = new SpannableString( "text4: Click here to dial the phone." );
 
ss.setSpan( new StyleSpan(Typeface.BOLD), 0 , 6 ,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 
ss.setSpan( new URLSpan( "tel:4155551212" ), 13 , 17 ,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 
TextView t4 = (TextView) findViewById(R.id.text4);
 
t4.setText(ss);
 
t4.setMovementMethod(LinkMovementMethod.getInstance());
  完整的代碼見 ApiDemo 吧,下面我提幾點須要注意的:
  .setMovementMethod,此方法在須要響應用戶事件時使用,如點擊一個電話號碼就跳轉到撥號頁面。若是不執行這個方法是不會響應事件的,即使文本看着已是下劃線藍色字了。
  .Spanned.SPAN_EXCLUSIVE_EXCLUSIVE,這是在 setSpan 時須要指定的 flag,它的意義我試了好久也沒試出來,睡個覺,今天早上才忽然有點想法,試之,果真。它是用來標識在 Span 範圍內的文本先後輸入新的字符時是否把它們也應用這個效果。分別有 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE(先後都不包括)、Spanned.SPAN_INCLUSIVE_EXCLUSIVE(前面包括,後面不包括)、Spanned.SPAN_EXCLUSIVE_INCLUSIVE(前面不包括,後面包括)、Spanned.SPAN_INCLUSIVE_INCLUSIVE(先後都包括)。看個截圖就更明白了:

  對比一下

  在Android中,TextView是咱們最經常使用的用來顯示文本的控件。
  通常狀況下,TextView中的文本都是一個樣式。那麼如何對於TextView中各個部分的文原本設置字體,大小,顏色,樣式,以及超級連接等屬性呢?下面咱們經過SpannableString的具體實例操做來演示一下。
  res-layout-main.xml:
  Java代碼
?
代碼片斷,雙擊複製
01
02
03
04
05
06
07
08
09
android:layout_height= "wrap_content" android:layout_width= "wrap_content" android:orientation= "horizontal" >
 
android:id= "@+id/myTextView"
 
android:layout_width= "fill_parent"
 
android:layout_height= "wrap_content"
 
/>
  res-color-color.xml
  res-color-linkcolor.xml:
  Java代碼
?
代碼片斷,雙擊複製
01
02
03
android:color= "#ffffff00" />
 
android:color= "#ff00ffff" />
  TextViewLinkActivity:
  Java代碼
?
代碼片斷,雙擊複製
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
import java.io.IOException;
 
import org.xmlpull.v1.XmlPullParserException;
 
import android.app.Activity;
 
import android.content.res.ColorStateList;
 
import android.content.res.XmlResourceParser;
 
import android.graphics.Bitmap;
 
import android.graphics.BitmapFactory;
 
import android.graphics.Color;
 
import android.graphics.drawable.Drawable;
 
import android.os.Bundle;
 
import android.text.SpannableString;
 
import android.text.Spanned;
 
import android.text.method.LinkMovementMethod;
 
import android.text.style.AbsoluteSizeSpan;
 
import android.text.style.BackgroundColorSpan;
 
import android.text.style.BulletSpan;
 
import android.text.style.DrawableMarginSpan;
 
import android.text.style.ForegroundColorSpan;
 
import android.text.style.IconMarginSpan;
 
import android.text.style.ImageSpan;
 
import android.text.style.RelativeSizeSpan;
 
import android.text.style.ScaleXSpan;
 
import android.text.style.StrikethroughSpan;
 
import android.text.style.StyleSpan;
 
import android.text.style.SubscriptSpan;
 
import android.text.style.SuperscriptSpan;
 
import android.text.style.TextAppearanceSpan;
 
import android.text.style.TypefaceSpan;
 
import android.text.style.URLSpan;
 
import android.text.style.UnderlineSpan;
 
import android.widget.TextView;
 
public class TextViewLinkActivity extends Activity {
 
TextView mTextView = null ;
 
SpannableString msp = null ;
 
/** Called when the activity is first created. */
 
@Override
 
public void onCreate(Bundle savedInstanceState) {
 
super .onCreate(savedInstanceState);
 
setContentView(R.layout.main);
 
mTextView = (TextView)findViewById(R.id.myTextView);
 
//建立一個 SpannableString對象
 
msp = new SpannableString( "字體測試字體大小一半兩倍前景色背景色正常粗體斜體粗斜體下劃線刪除線x1x2電話郵件網站短信彩信地圖X軸綜合/bot" );
 
//設置字體(default,default-bold,monospace,serif,sans-serif)
 
msp.setSpan( new TypefaceSpan( "monospace" ), 0 , 2 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 
msp.setSpan( new TypefaceSpan( "serif" ), 2 , 4 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 
//設置字體大小(絕對值,單位:像素)
 
msp.setSpan( new AbsoluteSizeSpan( 20 ), 4 , 6 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 
msp.setSpan( new AbsoluteSizeSpan( 20 , true ), 6 , 8 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //第二個參數boolean dip,若是爲true,表示前面的字體大小單位爲dip,不然爲像素,同上。
 
//設置字體大小(相對值,單位:像素) 參數表示爲默認字體大小的多少倍
 
msp.setSpan( new RelativeSizeSpan( 0 .5f), 8 , 10 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //0.5f表示默認字體大小的一半
 
msp.setSpan( new RelativeSizeSpan( 2 .0f), 10 , 12 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //2.0f表示默認字體大小的兩倍
 
//設置字體前景色
 
msp.setSpan( new ForegroundColorSpan(Color.MAGENTA), 12 , 15 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //設置前景色爲洋紅色
 
//設置字體背景色
 
msp.setSpan( new BackgroundColorSpan(Color.CYAN), 15 , 18 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //設置背景色爲青色
 
//設置字體樣式正常,粗體,斜體,粗斜體
 
msp.setSpan( new StyleSpan(android.graphics.Typeface.NORMAL), 18 , 20 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //正常
 
msp.setSpan( new StyleSpan(android.graphics.Typeface.BOLD), 20 , 22 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //粗體
 
msp.setSpan( new StyleSpan(android.graphics.Typeface.ITALIC), 22 , 24 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //斜體
 
msp.setSpan( new StyleSpan(android.graphics.Typeface.BOLD_ITALIC), 24 , 27 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //粗斜體
 
//設置下劃線
 
msp.setSpan( new UnderlineSpan(), 27 , 30 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 
//設置刪除線
 
msp.setSpan( new StrikethroughSpan(), 30 , 33 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 
//設置上下標
 
msp.setSpan( new SubscriptSpan(), 34 , 35 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //下標
 
msp.setSpan( new SuperscriptSpan(), 36 , 37 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //上標
 
//超級連接(須要添加setMovementMethod方法附加響應)
 
msp.setSpan( new URLSpan( "tel:4155551212" ), 37 , 39 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //電話
 
msp.setSpan( new URLSpan( "mailto:webmaster@google.com" ), 39 , 41 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //郵件
 
msp.setSpan( new URLSpan( "http://www.baidu.com" ), 41 , 43 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //網絡
 
msp.setSpan( new URLSpan( "sms:4155551212" ), 43 , 45 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //短信 使用sms:或者smsto:
 
msp.setSpan( new URLSpan( "mms:4155551212" ), 45 , 47 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //彩信 使用mms:或者mmsto:
 
msp.setSpan( new URLSpan( "geo:38.899533,-77.036476" ), 47 , 49 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //地圖
 
//設置字體大小(相對值,單位:像素) 參數表示爲默認字體寬度的多少倍
 
msp.setSpan( new ScaleXSpan( 2 .0f), 49 , 51 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //2.0f表示默認字體寬度的兩倍,即X軸方向放大爲默認字體的兩倍,而高度不變
 
//設置字體(依次包括字體名稱,字體大小,字體樣式,字體顏色,連接顏色)
 
ColorStateList csllink = null ;
 
ColorStateList csl = null ;
 
XmlResourceParser xppcolor=getResources().getXml (R.color.color);
 
try {
 
csl= ColorStateList.createFromXml(getResources(),xppcolor);
 
} catch (XmlPullParserException e){
 
// TODO: handle exception
 
e.printStackTrace();
 
} catch (IOException e){
 
// TODO: handle exception
 
e.printStackTrace();
 
}
 
XmlResourceParser xpplinkcolor=getResources().getXml(R.color.linkcolor);
 
try {
 
csllink= ColorStateList.createFromXml(getResources(),xpplinkcolor);
 
} catch (XmlPullParserException e){
 
// TODO: handle exception
 
e.printStackTrace();
 
} catch (IOException e){
 
// TODO: handle exception
 
e.printStackTrace();
 
}
 
msp.setSpan( new TextAppearanceSpan( "monospace" ,android.graphics.Typeface.BOLD_ITALIC, 30 , csl, csllink), 51 , 53 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 
//設置項目符號
 
msp.setSpan( new BulletSpan(android.text.style.BulletSpan.STANDARD_GAP_WIDTH,Color.GREEN), 0 ,msp.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //第一個參數表示項目符號佔用的寬度,第二個參數爲項目符號的顏色
 
//設置圖片
 
Drawable drawable = getResources().getDrawable(R.drawable.icon);
 
drawable.setBounds( 0 , 0 , drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
 
msp.setSpan( new ImageSpan(drawable), 53 , 57 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 
mTextView.setText(msp);
 
mTextView.setMovementMethod(LinkMovementMethod.getInstance());
 
}
 
}
  效果預覽:
  
相關文章
相關標籤/搜索