一、SpannableString与SpannableStringBuilder
1、SpannableString、SpannableStringBuilder与String的关系
SpannableString、SpannableStringBuilder与String基本上差不多,都是用来存储字符串的,但他们俩可以通过SetSpan()函数,给这些存储的String添加各种格式和样式,将原来的String以不同的样式显示出来,如给原来的String加上下划线、加背景颜色、改变字体颜色、用图片把制定文字替换等等。
注意:如果这些额外的信息能被所用的方式支持,比如讲SpannableString传给TextView;也有对这些额外信息不支持的,比如使用Canvas绘制文字,对于不支持的情况,SpannableString和SpannableStringBuilder将退化为String类型,直接显示原来的字符串,不显示额外的附加信息。
2、SpannableString与SpannableStringBuilder的区别
他们的区别就像String和StringBuilder的区别一样,一个是在传入String之后无法修改,另一个可以使用append来拼接多个String
//使用SpannableString,必须一次传入,构造完成
SpannableString word = new SpannableString("欢迎光临我的博客");
//使用SpannableStringBuilder,可以使用append()再添加
SpannableStringBuilder multiWord = new SpannableStringBuilder();
multiWord.append("欢迎光临");
multiWord.append("我的");
multiWord.append("博客");
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISOzcTM0ETNwITMwkDM0EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
因为SpannableString和SpannableStringBuilder都实现了CharSequence接口,可以直接通过TextView.setText()设置给TextView
3、SetSpan()方法
void setSpan(Object what, int start, int end, int flags)
函数意义:给SpannableString或SpannableStringBuilder特定范围的字符串设定Span样式,可以设置多个(比如同时加上下划线和删除线等),Falg参数标识了当在所标记范围前和标记范围后紧贴着插入新字符时的动作,即是否对新插入的字符应用同样的样式。(这个后面会具体举例说明)
参数说明:
object what :对应的各种Span,后面会提到;
int start:开始应用指定Span的位置,索引从0开始
int end:结束应用指定Span的位置,特效并不包括这个位置。比如如果这里数为3(即第4个字符),第4个字符不会有任何特效。从下面的例子也可以看出来。
int flags:取值有如下四个
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE:前后都不包括,即在指定范围的前面和后面插入新字符都不会应用新样式
Spannable.SPAN_EXCLUSIVE_INCLUSIVE:前面不包括,后面包括。即仅在范围字符的后面插入新字符时会应用新样式
Spannable.SPAN_INCLUSIVE_EXCLUSIVE:前面包括,后面不包括。
Spannable.SPAN_INCLUSIVE_INCLUSIVE:前后都包括。
举个例子来说明这个前后包括的问题:
由于Flag的作用是用来指定范围前后输入新的字符时,会不会应用效果的,所以我们利用EditText来显示SpannableString
(1)、布局XML中加入一个EditText控件:
[html] view plain copy
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context="com.example.try_spannable_blog.MainActivity" >
- <EditText
- android:id="@+id/edit"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
- </RelativeLayout>
(2)、这里用一个改变字体颜色的Span来做下演示
[java] view plain copy
- public class MainActivity extends Activity {
- private EditText editText;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- editText = (EditText)findViewById(R.id.edit);
- //改变字体颜色
- //先构造SpannableString
- SpannableString spanString = new SpannableString("欢迎光临Harvic的博客");
- //再构造一个改变字体颜色的Span
- ForegroundColorSpan span = new ForegroundColorSpan(Color.BLUE);
- //将这个Span应用于指定范围的字体
- spanString.setSpan(span, 1, 3, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
- //设置给EditText显示出来
- editText.setText(spanString);
- }
- }
初始化效果是这样的:
分别在设置Span的前面和后面加入新文字,结果是这样的
在前面和后面都加入虾米两个字,可见,前面的虾米没有任何效果,后面的则不同,添加上相同的Span特效,这是由于我们设置了Spannable.SPAN_EXCLUSIVE_INCLUSIVE的原因,即(前面不应用特效,后面应用特效),其它几个Flags参数的含义想必大家也都清楚了。在此就不再赘述。
4、使用:
使用起来一般分为三个步骤: 1、构造String 2、构造Span 3、使用setSpan给String设置样式
SpannableString spanString = new SpannableString("欢迎光临Harvic的博客");
//再构造一个改变字体颜色的Span
ForegroundColorSpan span = new ForegroundColorSpan(Color.BLUE);
//将这个Span应用于指定范围的字体
spanString.setSpan(span, 1, 5, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
//设置给EditText显示出来
editText.setText(spanString);
除了设置字体颜色 ForegroundColorSpan,另外还有字体背景颜色 BackgroundColorSpan,字体大小 AbsoluteSizeSpan,字体样式 StyleSpan,删除线 StrikethroughSpan,下划线 UnderlineSpan,图片置换 ImageSpan
二、DecimalFormat 和 BigDecimal
1、DecimalFormat
double d1 = 1234.5678;
double d2 = 111111111113.141592654;
//常用的Pattern字符为 0 和 #
//0 表示阿拉伯数字,本位没有也显示0
//# 表示阿拉伯数字,本位没有显示为空
//若小数位显示不全都会四舍五入
DecimalFormat df1 = new DecimalFormat("00000.00000");
DecimalFormat df2 = new DecimalFormat("##.###");
Log.d("test_decimalFormat", df1.format(d1)); //01234.56780
Log.d("test_decimalFormat", df2.format(d1)); //1234.568
DecimalFormat df3 = new DecimalFormat();
//以百分数的形式显示 并且保留两位小数, 0和#还是上面的意义
df3.applyPattern("#0.00%");
Log.d("test_decimalFormat", df3.format(d1)); //123456.78%
//以科学计数法的形式显示,保留4位小数E后面的字符必须是 0
df3.applyPattern("0.0000E0");
Log.d("test_decimalFormat", df3.format(d2)); //1.1111E11
//格式化输出 若高位没有明确的指出(如这里的万位)要按那种格式格式化,那么按照 第一个 , 为准
df3.applyPattern("#,###.000");
Log.d("test_decimalFormat", df3.format(d2)); //111,111,111,113.142
2、BigDecimal
可以将一个科学计数法表示的数字转换成double 或 float,可以直接这么使用 new BigDecimal("1.001E5");
下面附加一个连接,这里比较详细的描述了BigDecimal 的使用方法。
http://blog.csdn.net/jackiehff/article/details/8582449