String、StringBuffer、StringBuilder来自JDK
SpannableString、SpannableStringBuilder来自Android的API

先简单分析一下来自JDK的三个字符串的区别:

String:“字符串常量”(即定义字符串过后,就不能改变对象本身)

StringBuffer : “字符串变量”,线性安全

StringBuilder : “字符串变量”,线性不安全

我们再来分析一下Android中的API的字符串:

SpannableString : “字符串常量”,可与TextView搭配改变显示样式的字符串

SpannableStringBuilder : “字符串变量”,可与TextView搭配改变显示样式的字符串

具体分析:

来一段String的代码:

String str = "Hello World";str = str+"!";System.out.print(str);// result : Hello World!

这儿的str对象就改变了,不是说str是“字符串常量”,不是不能改变吗?但是上面说的是不能改变对象本身,这儿str的改变相当于是新建一个字符串对象,然后将新建的字符串对象赋值给str,也就说str已经不再是原来的str了

String与StringBuffer的对比

String str = "Hello " + "World" + "!";StringBuffer strBuffer= new StringBuffer("Hello ").append("World").append("!");

上面的代码你会发现String的创建速度很快,StringBuffer根本不占什么优势,那是因为String的创建相当于直接是String str = “Hello World!”,如果你改成下面这段代码,你就知道他们巨大的差别了

String str2 = "Hello "String str3 = "World";String str4 = "!";String str1 = str2 +str3 + str4;StringBuffer strBuffer= new StringBuffer("Hello ");strBuffer.append("World")strBuffer.append("!");

这时你会发现String与StringBuffer有很大的创建时间差别,String因为每次都需创建一个字符串对象,它的时间就会比StringBuffer耗时更久!

StringBuffer与StringBuilder的区别在于StringBuffer是线性安全的,StringBuilder是线性不安全的,什么是线性安全?线性安全是当程序中多个线程对同一个字符串操作时,StringBuilder无法保证在同一时刻只有一个线程对字符串操作,而StringBuffer它就能够保证线性安全,当然在耗时上StringBuffer要比StringBuilder耗时更久一点,但平时我们一般都在单线程中操作字符串,所以一般建议我们使用StringBuilder

SpannableString、SpannableStringBuilder和String的对比:

先来张图:

Android中五大字符串总结(String、StringBuffer、StringBuilder、SpannableString、SpannableStringBuilder)_第1张图片

这张图的代码实现并不是通过组合控件的方式实现的,其中只用了TextView,那为什么TextView会实现这么多功能,我们来看看代码:

MainActivity:

public class MainActivity extends AppCompatActivity {    private TextView mContent_1;    private TextView mContent_2;    private TextView mContent_3;    private TextView mContent_4;    private TextView mContent_5;    private TextView mContent_6;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();    }    private void initView() {        mContent_1 = (TextView) findViewById(R.id.activity_main_content_1);        mContent_2 = (TextView) findViewById(R.id.activity_main_content_2);        mContent_3 = (TextView) findViewById(R.id.activity_main_content_3);        mContent_4 = (TextView) findViewById(R.id.activity_main_content_4);        mContent_5 = (TextView) findViewById(R.id.activity_main_content_5);        mContent_6 = (TextView) findViewById(R.id.activity_main_content_6);        //设置字体颜色        SpannableString spannableString = new SpannableString("地心真的有外星人?");        ForegroundColorSpan colorSpan = new ForegroundColorSpan(Color.parseColor("#0000FF"));        spannableString.setSpan(colorSpan, 0, 4, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);        mContent_1.setText(spannableString);        //设置字体背景颜色        SpannableStringBuilder stringBuilder = new SpannableStringBuilder("我相信机器人的发展会统治地球!");        BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(Color.parseColor("#FF0000"));        stringBuilder.setSpan(backgroundColorSpan, 2, 5, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);        mContent_2.setText(stringBuilder);        //设置字体的大小        stringBuilder.append("真的吗?");        AbsoluteSizeSpan sizeSpan = new AbsoluteSizeSpan(20);        stringBuilder.setSpan(sizeSpan, 3, 6, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);        mContent_3.setText(stringBuilder);        //设置图片代替字体        ImageSpan imageSpan = new ImageSpan(this, R.mipmap.ic_launcher);        stringBuilder.setSpan(imageSpan, 3, 6, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);        mContent_4.setText(stringBuilder);        //设置点击事件        ClickableSpan clickableSpan = new ClickableSpan() {            @Override            public void onClick(View view) {                Toast.makeText(MainActivity.this, "不要点我,嘤嘤嘤", Toast.LENGTH_SHORT).show();            }        };        stringBuilder.setSpan(clickableSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);        mContent_5.setText(stringBuilder);        //代码中的index为0的字为可点击文本,其他区域不可点击        mContent_5.setMovementMethod(LinkMovementMethod.getInstance());        //再写个设置下划线        spannableString = new SpannableString("你相信有人会一直做某个连续的梦吗?");        UnderlineSpan underlineSpan = new UnderlineSpan();        spannableString.setSpan(underlineSpan, 11, 15, Spanned.SPAN_EXCLUSIVE_INCLUSIVE);        mContent_6.setText(spannableString);    }}

activity_main.xml:
(使用了一个ConstraintLayout布局,大家有可能更多的知道他是可以实现手拖控件的布局,但是你也可以自己写它里面的xml属性,并且它的功能比以前的五大布局都厉害, 而且使用它几乎不再需要布局嵌套了,大大节省了手机CPU渲染的时间,大家有时间可以去了解了解)

<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout 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"    tools:context="com.leezp.xingyun.strtype.MainActivity">    <TextView        android:id="@+id/activity_main_content_1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Hello World!"        android:layout_marginTop="20dp"        app:layout_constraintLeft_toLeftOf="parent"        app:layout_constraintRight_toRightOf="parent"        app:layout_constraintTop_toTopOf="parent" />    <TextView        android:id="@+id/activity_main_content_2"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="love is foam"        android:layout_marginTop="20dp"        app:layout_constraintLeft_toLeftOf="parent"        app:layout_constraintRight_toRightOf="parent"        app:layout_constraintTop_toBottomOf="@id/activity_main_content_1"/>    <TextView        android:id="@+id/activity_main_content_3"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="One's mind settles as still water"        android:layout_marginTop="20dp"        app:layout_constraintLeft_toLeftOf="parent"        app:layout_constraintRight_toRightOf="parent"        app:layout_constraintTop_toBottomOf="@id/activity_main_content_2"/>    <TextView        android:id="@+id/activity_main_content_4"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Eat without words and sleep without words"        android:layout_marginTop="20dp"        app:layout_constraintLeft_toLeftOf="parent"        app:layout_constraintRight_toRightOf="parent"        app:layout_constraintTop_toBottomOf="@id/activity_main_content_3"/>    <TextView        android:id="@+id/activity_main_content_5"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="When the mountains are high, the mountains are small"        android:layout_marginTop="20dp"        app:layout_constraintLeft_toLeftOf="parent"        app:layout_constraintRight_toRightOf="parent"        app:layout_constraintTop_toBottomOf="@id/activity_main_content_4"/>    <TextView        android:id="@+id/activity_main_content_6"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Jungle law"        android:layout_marginTop="20dp"        app:layout_constraintLeft_toLeftOf="parent"        app:layout_constraintRight_toRightOf="parent"        app:layout_constraintTop_toBottomOf="@id/activity_main_content_5"/>android.support.constraint.ConstraintLayout>

最后听说低版本的Android系统在TextView设置ClickableSpan与OnClickListener时,会出现两个事件会被同时触发,所以这儿给了个参考解决办法

SpannableString与SpannableStringBuilder设置样式的主要的方法:

通过使用setSpan(Object what, int start, int end, int flags)改变文本样式。

对应的参数:

start: 指定Span的开始位置
end: 指定Span的结束位置,并不包括这个位置。
flags:取值有如下四个
Spannable. SPAN_INCLUSIVE_EXCLUSIVE:前面包括,后面不包括,即在文本前插入新的文本会应用该样式,而在文本后插入新文本不会应用该样式
Spannable. SPAN_INCLUSIVE_INCLUSIVE:前面包括,后面包括,即在文本前插入新的文本会应用该样式,而在文本后插入新文本也会应用该样式
Spannable. SPAN_EXCLUSIVE_EXCLUSIVE:前面不包括,后面不包括
Spannable. SPAN_EXCLUSIVE_INCLUSIVE:前面不包括,后面包括
what: 对应的各种Span,不同的Span对应不同的样式。已知的可用类有:
BackgroundColorSpan : 文本背景色
ForegroundColorSpan : 文本颜色
MaskFilterSpan : 修饰效果,如模糊(BlurMaskFilter)浮雕
RasterizerSpan : 光栅效果
StrikethroughSpan : 删除线
SuggestionSpan : 相当于占位符
UnderlineSpan : 下划线
AbsoluteSizeSpan : 文本字体(绝对大小)
DynamicDrawableSpan : 设置图片,基于文本基线或底部对齐。
ImageSpan : 图片
RelativeSizeSpan : 相对大小(文本字体)
ScaleXSpan : 基于x轴缩放
StyleSpan : 字体样式:粗体、斜体等
SubscriptSpan : 下标(数学公式会用到)
SuperscriptSpan : 上标(数学公式会用到)
TextAppearanceSpan : 文本外貌(包括字体、大小、样式和颜色)
TypefaceSpan : 文本字体
URLSpan : 文本超链接
ClickableSpan : 点击事件

参考资料

String、StringBuffer与StringBuilder之间区别
【Android】强大的SpannableStringBuilder
Android项目实战(一): SpannableString与SpannableStringBuilder

更多相关文章

  1. Android文本输入框EditText的属性和方法
  2. 【Android】 _UI设计_图片滑动样式
  3. android启动activity文本框不打开输入法界面
  4. Android-string.xml动态替换文本
  5. SeekBar自定义样式
  6. 自定义ProgressBar样式

随机推荐

  1. Android 使用 unity 导出obb包
  2. Android 学习系列 - 线程模型
  3. 第一次使用Android Studio时你应该知道的
  4. 优化你的代码结构 --- MVP
  5. WebView加入动画后白屏卡顿的现象
  6. Android基本界面控件
  7. RecyclerView机制解析: ItemDecoration
  8. Android白眉鹰王之BroadcastReceiver
  9. Android eclipse 没有Annotation Process
  10. Android自带音乐播放器代码分析(1)