標籤:
在應用開發中時常會遇到需要在一段文字中插入幾個不一樣顏色文字的需求;
以前本人都是用多個TextView拼起來,不僅感覺很蠢,操作起來也蠻噁心;
直到接觸到了SpannableStringBuilder,感覺整個人都好了;
在我搭建介面布局,會有一些帶String預留位置的預設文字,如:"現在的氣溫是:%s","今天天氣:%1$s,最高氣溫:%2$s,最低氣溫:%3$s,降雨率:%4$s,pm2.5:%5$s.";
之後在擷取到資料時,直接String.format(String target, String... data),就能在對應位置插入資料;
最近遇到一個插入的資料還要換成另一種顏色的需求,覺得這個需求應該比較常見,所以就寫了個工具類;
1 /** 2 * TextView色彩工具類 3 * Created by me on 2015-08-10. 4 */ 5 public class TextViewColorUtil { 6 7 /** 8 * 在文字內容為"xxxxx%sxxxx"(一個格式化預留位置)或"xxxx%1$sxxxx%2$x......xxxx%n$sxxxx"時(多個格式化預留位置),完成格式化同時,設定新加入的文字顏色,同時也能夠設定原來文字的顏色; 9 * <p/>10 * 注:請務必保證單個格式化時,使用%s預留位置;多格式化時,使用%n$s預留位置;11 * 預留位置數必須和想填入的字串數目一致;12 *13 * @param texts 如果可變參數長度為0,不做處理;如果文字長度為0,預設為""14 * @param defaultColorId R.color.xxx 如果不想改變預設顏色(冒號前的文字顏色),可以填null15 * @param newContentColorId R.color.xxx16 */17 public static void setSubColorText(Context context, TextView tv, Integer defaultColorId, int newContentColorId, String... texts) {18 19 if (texts != null) {20 if (texts.length == 1) {//單格式化參數情況21 if (defaultColorId != null)//1.如果有設定改編預設文字顏色,給予改變22 tv.setTextColor(defaultColorId);23 24 String text = texts[0];25 if (StringUtil.isEmpty(text))//2.如果文字內容為null或者長度0,預設其為""26 text = "";27 28 String originText = tv.getText().toString();//3.格式化,記錄添加的字串的起止index29 int indexStart = originText.indexOf("%s");30 int indexEnd = indexStart + text.length();31 String foo = String.format(originText, text);32 tv.setText(foo);33 34 if (indexEnd > indexStart) {//4.如果有必要換色,執行35 SpannableStringBuilder style = new SpannableStringBuilder(foo);36 style.setSpan(new ForegroundColorSpan(context.getResources().getColor(newContentColorId)), indexStart, indexEnd, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);37 tv.setText(style);38 }39 40 } else if (texts.length > 1) {//多格式化41 if (defaultColorId != null)//1.如果有設定改編預設文字顏色,給予改變42 tv.setTextColor(defaultColorId);43 44 int[] indexesStart = new int[texts.length];45 int[] indexesEnd = new int[texts.length];46 String originText = tv.getText().toString();47 48 for (int i = 0; i < texts.length; i++) {49 String text = texts[i];50 if (StringUtil.isEmpty(text)) {//2.如果文字內容為null或者長度0,預設其為""51 text = "";52 }53 54 String regular = "%" + (i + 1) + "$s";//3.格式化,記錄添加的字串的起止index55 indexesStart[i] = originText.indexOf(regular);56 if (i > 0) {57 int indexFix = 0;58 for (int j = 0; j <= i - 1; j++) {59 String formerRegular = "%" + (j + 1) + "$s";60 indexFix += (indexesEnd[j] - indexesStart[j]) - formerRegular.length();61 }62 indexesStart[i] += indexFix;63 }64 indexesEnd[i] = indexesStart[i] + text.length();65 }66 String foo = String.format(originText, (Object[]) texts);67 tv.setText(foo);68 SpannableStringBuilder style = new SpannableStringBuilder(foo);69 for (int i = 0; i < texts.length; i++) {70 if (indexesEnd[i] > indexesStart[i])//4.如果有必要換色,執行71 style.setSpan(new ForegroundColorSpan(context.getResources().getColor(newContentColorId)), indexesStart[i], indexesEnd[i], Spannable.SPAN_INCLUSIVE_EXCLUSIVE);72 }73 tv.setText(style);74 }75 }76 }77 }Code
目前只有一種顏色,如果有每個插入的資料還要不同色彩的需求...也蠻好改的.
把傳入的參數int newContentColorId換成int[] newContentColorIds然後稍微改改邏輯就ok啦.
>_>
就以之前的兩個例子舉例吧:
1.
1 textView.setText("現在的氣溫是:%s");2 TextViewColorUtil.setSubColorText(MainActivity.this, textView, null, R.color.blue,"3°c");"現在的氣溫是:%s"
2.
1 tv.setText("今天天氣:%1$s,最高氣溫:%2$s,最低氣溫:%3$s,降雨率:%4$s,pm2.5:%5$s.");2 TextViewColorUtil.setSubColorText(MainActivity.this, tv, null, R.color.red, "晴", "22°c", "9°c", "47%", "19");"今天天氣:%1$s,最高氣溫:%2$s,最低氣溫:%3$s,降雨率:%4$s,pm2.5:%5$s."
Android TextView設定多彩文字