一直想写一个工具类,使TextView显示不同颜色的文字,实现方法有几种,今天,使用的是StringBuilder拼接Html的方式
textView.setText(Html.fromHtml(builder.toString()));
下面是效果图:
使用起来应该能让大家满意
//拼接模式
TextUtil.create()
.addSection("这是")
.addTintSection("绿色",0x00ff00)
.addSection("字体,这是")
.addTintSection("蓝色",0x0000ff)
.addSection("字体。")
.showIn(mTvPackage);
//上色模式
TextUtil.create()
.addSection("这是红色字体,这是蓝色字体,这是绿色字体。")
.tint("红色", 0xff0000)
.tint("蓝色", 0x0000ff)
.tint("绿色", 0x00ff00)
.tint("字体", Color.CYAN)
.tint("这是", Color.MAGENTA)
.showIn(mTipView);
接下来上代码:
import android.support.annotation.NonNull;
import android.text.Html;
import android.util.Log;
import android.widget.TextView;
/**
* TextUtil
* 拼接不同颜色文字的工具类--建造者模式
* Created by wangzhengyang on 2017/2/20.
* 使用:
*
//拼接模式
TextUtil.create()
.addSection("这是")
.addTintSection("绿色",0x00ff00)
.addSection("字体,这是")
.addTintSection("蓝色",0x0000ff)
.addSection("字体。")
.showIn(mTvPackage);
//上色模式
TextUtil.create()
.addSection("这是红色字体,这是蓝色字体,这是绿色字体。")
.tint("红色", 0xff0000)
.tint("蓝色", 0x0000ff)
.tint("绿色", 0x00ff00)
.tint("字体", Color.CYAN)
.tint("这是", Color.MAGENTA)
.showIn(mTipView);
*/
public final class TextUtil {
private static final String TAG = "TextUtil";
public static Builder create() {
return new Builder();
}
public static class Builder {
private StringBuilder builder;
public Builder() {
builder = new StringBuilder();
}
public Builder addSection(@NonNull String section) {
builder.append(section);
return this;
}
public Builder configColor(int color) {
builder.append("");
return this;
}
public Builder complete() {
builder.append("");
return this;
}
public Builder addTintSection(@NonNull String section, int color){
return configColor(color).addSection(section).complete();
}
public Builder tint(String section, int color) {
int fromIndex = 0;
int count = 0;
while (true){
int startIndex = getSection().indexOf(section, fromIndex);
if (startIndex == -1) break;
int endIndex = startIndex + section.length();
tint(section, startIndex, endIndex, color);
String concat = section.concat("");
fromIndex = getSection().lastIndexOf(concat) + concat.length();
++count;
}
Log.i(TAG, "tint: count = " + count);
return this;
}
private Builder tint(String section, int startIndex, int endIndex, int color) {
section = create().addTintSection(section, color).getSection();
builder.replace(startIndex, endIndex, section);
return this;
}
public void showIn(TextView textView) {
textView.setText(Html.fromHtml(builder.toString()));
builder = null;
}
public String getSection() {
return builder.toString();
}
}
}
注释中的使用方式是可用方式,另外
拼接模式还可以使用这种方式:
TextUtil.create()
.addSection("这是")
.configColor(0xff0000)
.addSection("红色")
.complete()
.addSection("字体")
.showIn(textView);
不是很简便,不提倡使用。
还有就是,在染色模式中,有这种情况:
字符串“这是红色字体,这是蓝色字体,这是绿色字体”,里面有3个“这是”,3个“字体”,由于当前工具类使用的是拼接html再
显示到TextView中的。又因为StringBuilder索引 字符\字符串 只要找到一个就返回索引值,要么indexOf(),要么lastIndexOf()
所以需要做处理。见代码中方法
public Builder tint(String section, int color) {
int fromIndex = 0;
int count = 0;
while (true){
int startIndex = getSection().indexOf(section, fromIndex);
if (startIndex == -1) break;
int endIndex = startIndex + section.length();
tint(section, startIndex, endIndex, color);
String concat = section.concat("</font>");
fromIndex = getSection().lastIndexOf(concat) + concat.length();
++count;
}
Log.i(TAG, "tint: count = " + count);
return this;
}
int fromIndex = 0;
int count = 0;
while (true){
int startIndex = getSection().indexOf(section, fromIndex);
if (startIndex == -1) break;
int endIndex = startIndex + section.length();
tint(section, startIndex, endIndex, color);
String concat = section.concat("</font>");
fromIndex = getSection().lastIndexOf(concat) + concat.length();
++count;
}
Log.i(TAG, "tint: count = " + count);
return this;
}
使得效果如效果图所示,
字符串“这是红色字体,这是蓝色字体,这是绿色字体”中,所有“这是”和“字体”都变了颜色。
是不是很好用?
Bug:
但是,拼接模式没有问题,但上色模式有很多bug,因为使用的是将相应字段替换成Html,所以,当为数字和一些字符串(如,font,fon,fo,o等,与<font color='254234234134'></font>中某几个字符相同)就会把html坏掉,出现问题。
所以需要换种方案:使用:SpannableStringBuilder
关于文字颜色,另请参看博客(lison):
http://blog.csdn.net/luckily01/article/details/7710242