1TextView的富文本介绍:
什么是富文本,大家都知道TextView可以显示文字,设置文字样式,利用富文本可以给TextView添加更多的样式,更加的类似h5网页,例如在一个TextView通常显示的文本样式是统一的,如果想对显示的同一段文本不同部分的文字设置不同的样式,颜色,大小等就需要用到富文本,富文本还可以利用TextView显示图片,设置点击事件等。
TextView想要实现富文本可以利用SpannableString(SpannableStringBuilder )和Html工具类,其实Html的工具类方式内部也是利用了SpannableString实现。
TextView可以利用setText设置文本,SpannableString实现了CharSequence,所以可以直接设置给TextView实现富文本。
常用span:
BackgroundColorSpan(背景色)、ForegroundColorSpan(设置字体颜色)、AbsoluteSizeSpan(设置字体大小)、UnderlineSpan(下划线),URLSpan(设置链接)、ClickableSpan(点击事件)、StyleSpan(样式,可以设置粗体,斜体等)、ImageSpan(图片Span)、RelativeSizeSpan(相对字体大小,就是设置字体大小的倍数)、ScaleXSpan(横向压缩字体)、SubscriptSpan(设置下标)、SuperscriptSpan(设置上标)、TextAppearanceSpan(也是设置文字样式)、TypefaceSpan(设置字体)、RasterizerSpan(设置光栅字样)、StrikethroughSpan(删除线)。
** 注意:
TextView必须设置 setMovementMethod(LinkMovementMethod.getInstance());
在使用ClickableSpan和继承ClickableSpan的时候,单击链接时凡是有要运行的动作,都必须设置MovementMethod对象。**
2 使用Span的方式
- 利用SpannableString(SpannableStringBuilder )包装文本
- 利用setSpan设置特定的span样式
setSpan方法说明
void setSpan (Object what, int start, int end, int flags)
参数说明:
what:生成的Span对象(特定span)
start:开始位置,从0开始计数
end:结束位置,应用span样式的文本长度为end-start
flags:对于新插入字符的处理
Flags 取值:
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE:前后都不包括,意义是如果在设置了span的文本前后插入新的SpannableString文本都不会应用span样式。
Spanned.SPAN_EXCLUSIVE_INCLUSIVE:前面不包括,后面包括,在设置的span前插入新的SpannableString不会应用span样式,在设置的span后插入则会应用相应span
Spanned.SPAN_INCLUSIVE_EXCLUSIVE:前面包括,后面不包括,在设置的span前插入新的SpannableString会应用span样式,在设置的span后插入则不会应用相应span
Spanned.SPAN_INCLUSIVE_INCLUSIVE:前后都包括,在设置的span前后插入新的SpannableString文本都会应用相应span
举例:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".SpanTestActivity">
<TextView
android:id="@+id/textview1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="17sp"
android:layout_marginTop="10dp"
android:text="用户名 回复 测试span:" />
<TextView
android:id="@+id/textview2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="17sp"
android:layout_marginTop="10dp"
android:text="用户名 回复 测试span:" />
<TextView
android:id="@+id/textview3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="17sp"
android:layout_marginTop="10dp"
android:text="用户名 回复 测试span:" />
<TextView
android:id="@+id/textview4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="17sp"
android:layout_marginTop="10dp"
android:text="用户名 回复 测试span:" />
<TextView
android:id="@+id/textview5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="17sp"
android:layout_marginTop="10dp"
android:text="用户名 回复 测试span:" />
<TextView
android:id="@+id/textview6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="17sp"
android:layout_marginTop="10dp"
android:text="用户名 回复 测试span:" />
<TextView
android:id="@+id/textview7"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="17sp"
android:layout_marginTop="10dp"
android:text="用户名 回复 测试span:" />
</LinearLayout>
public class SpanTestActivity extends AppCompatActivity {
private TextView mTextView1;
private TextView mTextView2;
private TextView mTextView3;
private TextView mTextView4;
private TextView mTextView5;
private TextView mTextView6;
private TextView mTextView7;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_span_test);
mTextView1 = findViewById(R.id.textview1);
mTextView2 = findViewById(R.id.textview2);
mTextView3 = findViewById(R.id.textview3);
mTextView4 = findViewById(R.id.textview4);
mTextView5 = findViewById(R.id.textview5);
mTextView6 = findViewById(R.id.textview6);
mTextView7 = findViewById(R.id.textview7);
SpannableStringBuilder spannableStringBuilder1 = new SpannableStringBuilder("测试富文本样式设");
ForegroundColorSpan fspan1 = new ForegroundColorSpan(Color.RED);
//从4-8,应用span的文本长度为8-4=4,所以就是从0开始第四个字符“本”开始,然后长度为4到"设“结束
//应用了SPAN_INCLUSIVE_INCLUSIVE模式,所以后面添加的文本都会应用fspan的样式
spannableStringBuilder1.setSpan(fspan1,4,8, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
SpannableString textSpanned1 = new SpannableString("置字体颜色设置");
spannableStringBuilder1.append(textSpanned1);
mTextView1.setText(spannableStringBuilder1);
SpannableStringBuilder spannableStringBuilder2 = new SpannableStringBuilder("测试富文本样式设");
ForegroundColorSpan fspan2 = new ForegroundColorSpan(Color.RED);
//从4-8,应用span的文本长度为8-4=4,所以就是从0开始第四个字符“本”开始,然后长度为4到"设“结束
//应用了SPAN_INCLUSIVE_EXCLUSIVE模式,所以后面添加的文本不会应用fspan的样式
spannableStringBuilder2.setSpan(fspan2,4,8, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
SpannableString textSpanned2 = new SpannableString("置字体颜色设置");
spannableStringBuilder2.append(textSpanned2);
mTextView2.setText(spannableStringBuilder2);
SpannableStringBuilder spannableStringBuilder3 = new SpannableStringBuilder("测试富文本样式设");
ForegroundColorSpan fspan3 = new ForegroundColorSpan(Color.RED);
spannableStringBuilder3.setSpan(fspan3,4,8, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
SpannableString textSpanned3 = new SpannableString("置字体颜色设置");
spannableStringBuilder3.append(textSpanned3);
spannableStringBuilder3.append("添加设置");
mTextView3.setText(spannableStringBuilder3);
SpannableStringBuilder spannableStringBuilder4 = new SpannableStringBuilder("测试富文本样式设");
ForegroundColorSpan fspan4 = new ForegroundColorSpan(Color.RED);
spannableStringBuilder4.setSpan(fspan4,4,8, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
SpannableString textSpanned4 = new SpannableString("置字体颜色设置");
textSpanned4.setSpan(new ForegroundColorSpan(Color.BLUE),0,7,Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableStringBuilder4.append(textSpanned4);
spannableStringBuilder4.append("添加设置");
mTextView4.setText(spannableStringBuilder4);
SpannableStringBuilder spannableStringBuilder5 = new SpannableStringBuilder("测试富文本样式设");
ForegroundColorSpan fspan5 = new ForegroundColorSpan(Color.RED);
spannableStringBuilder5.setSpan(fspan5,4,8, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
SpannableString textSpanned5 = new SpannableString("置字体颜色设置");
textSpanned5.setSpan(new ForegroundColorSpan(Color.BLUE),0,7,Spanned.SPAN_INCLUSIVE_INCLUSIVE);
spannableStringBuilder5.append(textSpanned5);
spannableStringBuilder5.append("添加设置");
mTextView5.setText(spannableStringBuilder5);
SpannableString spannableString16 = new SpannableString("测试富文本样式设");
ForegroundColorSpan fspan6 = new ForegroundColorSpan(Color.RED);
spannableString16.setSpan(fspan6,4,8, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
SpannableString spannableString26 = new SpannableString("置字体颜色设置");
spannableString26.setSpan(new ForegroundColorSpan(Color.BLUE),0,5,Spanned.SPAN_INCLUSIVE_INCLUSIVE);
mTextView6.setText(new SpannableStringBuilder().append(spannableString16).append(spannableString26).append("添加设置"));
}
}
所以可以得出如下结论:
- flags会影响添加的SpannableString文本的样式,四种flag分别表示是否影响前后添加的文本。
- 受影响的文本长度为从start开始,长度为end-start,
- 如果设置了影响添加的文本,但是新设置的文本内部应用了新的span样式,会首先应用内部文本添加的span,后续再添加文本也会受上次新添加Span的影响,如果新添加的文本不受上次添加span的影响,则会受更上层span的影响。
4 常用的Span举例:
上面已经展示了ForegroundColorSpan(设置字体颜色),下面介绍一些常用的span;
SpannableString span1 = new SpannableString("测试富文本样式设置");
SpannableString span2 = new SpannableString("测试富文本样式设置");
SpannableString span3 = new SpannableString("测试富文本样式设置");
SpannableString span4 = new SpannableString("测试富文本样式设置");
SpannableString span5 = new SpannableString("测试富文本样式设置");
SpannableString span6 = new SpannableString("测试富文本样式设置");
SpannableString span7 = new SpannableString("测试富文本样式设置");
BackgroundColorSpan bgSpan = new BackgroundColorSpan(Color.BLUE);
AbsoluteSizeSpan sizeSpan = new AbsoluteSizeSpan(22);
UnderlineSpan underline = new UnderlineSpan();
StrikethroughSpan deleteLine = new StrikethroughSpan();
SubscriptSpan subspan = new SubscriptSpan();
span1.setSpan(bgSpan,0,5,Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
mTextView1.setText(span1);
span2.setSpan(sizeSpan,0,4,Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
mTextView2.setText(span2);
span3.setSpan(underline,0,4,Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
mTextView3.setText(span3);
span4.setSpan(deleteLine,0,4,Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
mTextView4.setText(span4);
span5.setSpan(subspan,0,4,Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
mTextView5.setText(span5);
//必须设置LinkMovementMethod
mTextView6.setMovementMethod(LinkMovementMethod.getInstance());
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(View widget) {
Toast.makeText(SpanTestActivity.this,"click",Toast.LENGTH_SHORT).show();
}
};
span6.setSpan(clickableSpan,0,5,Spanned.SPAN_INCLUSIVE_INCLUSIVE);
mTextView6.setText(span6);
//设置LinkMovementMethod ,利用默认浏览器打开
mTextView7.setMovementMethod(LinkMovementMethod.getInstance());
URLSpan urlSpan = new URLSpan("http://www.baidu.com");
span7.setSpan(urlSpan,0,9,Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
mTextView7.setText(span7);
5 Html工具类方式设置富文本
书写类似html格式代码,然后利用Html工具类也可以实现富文本,内部利用SpannableString。
支持的样式:
String htmlText1 = "<big>大号字体</big>";
mTextView1.setText(Html.fromHtml(htmlText1));
String htmlText2 = "<i>大号字体<i>";
mTextView2.setText(Html.fromHtml(htmlText2));
String htmlText3 = "大号<br>字体";
mTextView3.setText(Html.fromHtml(htmlText3));
String htmlText4 = "大号<p>字体";
mTextView4.setText(Html.fromHtml(htmlText4));
String htmlText5 = "<img src=\"ic_launcher\"/>";
mTextView5.setText(Html.fromHtml(htmlText5, new Html.ImageGetter() {
@Override
public Drawable getDrawable(String source) {
Drawable draw = null;
try {
Field field = R.mipmap.class.getField(source);
int resourceId = Integer.parseInt(field.get(null).toString());
draw = getResources().getDrawable(resourceId);
draw.setBounds(0, 0, draw.getIntrinsicWidth(), draw.getIntrinsicHeight());
} catch (Exception e) {
e.printStackTrace();
}
return draw;
}
}, null));
}