Android-如何讓優雅地讓一個TextView顯示兩種樣式的字型
分享優雅寫程式碼的一個小技巧~
前言
這是一個很常見的需求,一般出現在有單位的資料展示上面。例如下面的兩個例子,來源於我司專案的某一個頁面。
如果讓你實現圖一的3.07萬元
和圖二的 您的估價低於 80% 車主的估價
,你會怎麼佈局?
如果是以前的我:
圖一的3.07萬元
會換成 3.07
和 萬元
兩個 TextView 顯示,因為倆大小不一樣,這個理由尚能接受。
圖二,會換成 3 個 TextView 顯示,因為顏色不一樣,而且顏色不一樣的還在中間。嗯,這個說出來就感覺有點丟臉了。
然而現在我想說,事實上,這兩者都可以只用一個 TextView 展示。
而且方式還不只一種:
- TextView 顯示 Html 樣式
- SpannableString
下面分別用這兩種方式實現一下。
Html 方式
有這麼一個方法:
Html.fromHtml()
該方法可以將一段 html 字串顯示為TextView 可以顯示的樣式文字。
於是,首先根據需求編寫好 html ,通過該方法轉換文字,拿給 TextView 顯示即可。
如下:
tv1.setText(Html.fromHtml("<font color=\'#217aff\' ><big>3.07</big></font><font color =\'#217aff\' ><small>萬元</small></font>"));
tv2.setText(Html.fromHtml("<font color=\'#656565\'>您的估價</font><font color=\'#f48421\'>低於</font><font color=\'#656565\'>80%車主的售價。</font>"));
顯示效果:
另外,大家注意到上面 3.07萬元
中兩個字型大小不同,我是通過 <big>3.07</big>
<small>萬元</small>
去控制的。這個是因為 Android 中只支援 標籤的 color 和 face 標籤,不支援 size 標籤。所以像下面的樣式,無法顯示 size 大小的。
"<font color=\'#217aff\' size=\'18px\' >3.07</font><font color=\'#217aff\' size=\'10px\'>萬元</font>"
想控制大小隻能通過 <big>
和 <small>
標籤,但是兩者的大小比較固定,沒辦法精確控制。如果遇到需要控制字型大小的需求,可以考慮用下面的 SpannableString 來實現。
SpannableString 方式
SpannableString 實現了 CharSequence 介面,所以無須轉換, TextView 可以直接通過 setText() 方法顯示。
先使用 SpannableString 實現上面的例子感受一下:
// “3.07 萬元”的實現方式
SpannableString s1 = new SpannableString("3.07萬元");
s1.setSpan(new AbsoluteSizeSpan(18, true), 0, s1.length()-2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
s1.setSpan(new AbsoluteSizeSpan(10, true), s1.length()-2, s1.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tv3.setTextColor(Color.parseColor("#217aff"));
tv3.setText(s1);
// “80%車主的估價”的實現方式
SpannableString s2 = new SpannableString("您的估價低於80%車主的估價");
s2.setSpan(new ForegroundColorSpan(Color.parseColor("#656565")), 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
s2.setSpan(new ForegroundColorSpan(Color.parseColor("#f48421")), 4, 6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
s2.setSpan(new ForegroundColorSpan(Color.parseColor("#656565")), 6, s2.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tv4.setText(s2);
顯示效果:
是不是很贊,來看一下實現過程:
第一步:建立一個SpannableString。
SpannableString spannableString = new SpannableString("3.07萬元");
第二步:使用 setSpan() 給 SpannableString 設定樣式。
spannableString.setSpan(Object what, int start, int end, int flags);
引數的意義是:
- what:對SpannableString進行潤色的各種Span;
- start:需要潤色文欄位開始的下標;
- end:需要潤色文欄位結束的下標;
- flags:標誌位,決定操作的範圍是否包含開始和結束下標,有四個引數可選,為什麼有四個?因為分別代表著 start 至 end 的四種集合開閉模式。
- SPAN_INCLUSIVE_EXCLUSIVE:[start,end) 包括開始下標,但不包括結束下標
- SPAN_EXCLUSIVE_INCLUSIVE:(start,end] 不包括開始下標,但包括結束下標
- SPAN_INCLUSIVE_INCLUSIVE:[start,end] 既包括開始下標,又包括結束下標
- SPAN_EXCLUSIVE_EXCLUSIVE:(start,end) 不包括開始下標,也不包括結束下標
總體是第一個引數決定效果,後三個引數決定範圍,顯而易見,第一個引數是非常的需要去好好認識,把酒言歡一下的。
SpannableString 提供了很多 Span 樣式供開發者們選擇,有用來設定大小,顏色,下劃線,甚至還有點選事件的。我找了它們的繼承結構圖,截來給大家看一下 Span 們的家譜。
上面例子中只用到了兩個樣式, ForegroundColorSpan 設定字型前景顏色,AbsoluteSizeSpan 設定字型大小,非常的簡單。其實 Span 們功能遠不止這些,但是這裡不贅述了,大家可以自己多去嘗試,下面是我覺得比較好的文章連結分享。
另外一個新 Get 的小知識點
真實的專案開發中,想 3.07萬元
這種字串不可能是固定好的,肯定是有服務端返回的,但是有的只是純數字。那麼除了用 +
號拼接,還可以這樣使用:
String s = String.format("%s萬元",3.07);
關於這個 String.format()
方法也是最近才發現的一個小技巧,使用上感覺比+
要更方便,也更直觀,關於它的更多資訊可以直接看官方文件,大概瞭解掌握其功能,記住幾個最常用的,其他的可以隨用隨查。
最後
哈哈哈,覺得自己之前好笨拙,可能現在也是,不過有這個感覺也證明現在變的好一點了吧,雖然是一個很小的知識點。荀子老人家說了:“不積跬步,無以至千里;不積小流,無以成江海。”,希望我們都越來越好。
下篇部落格見。
歡迎關注博主的微信公眾號,快快加入哦,期待與你一起成長!