*像word一样编辑复杂的文本:SpannableString 样式详介
1.简介
使用android.text.Spanned; android.text.SpannableString; android.text.SpannableStringBuilder; 和 android.text.*;和 android.text.style.*;
系列类,可以像word一样编辑复杂的文本,如:粗体,字体,横线,插入图片,超链接等。这个文本可以被TextView,EditText等使用。
SpannableString像一个String一样,构造对象的时候传入一个String,之后再无法更改String的内容,也无法拼接多个 SpannableString;而SpannableStringBuilder则更像是StringBuilder,它可以通过其append()方法来拼接多个String。
2.重要方法
SpannableString的重要方法 void setSpan(Object what, int start, int end, int flags)。
函数意义:
给SpannableString或SpannableStringBuilder特定范围的字符串设定Span样式,可以设置多个(比如同时加上下划线和删除线等),Falg参数标识了当在所标记范围前和标记范围后紧贴着插入新字符时的动作,即是否对新插入的字符应用同样的样式。
参数说明:
object what:对应的各种Span,后面会提到;int start:开始应用Span的位置,索引从0开始int end:结束应用Span的位置,特效并不包括这个位置。比如end值为3(即第4个字符),第4个字符不会有任何特效。从下面的例子也可以看出来。int flags:取值有如下四个
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE:前后都不包括,即在指定范围的前面和后面插入新字符都不会应用新样式
Spannable.SPAN_EXCLUSIVE_INCLUSIVE:前面不包括,后面包括。即仅在范围字符的后面插入新字符时会应用新样式Spannable.SPAN_INCLUSIVE_EXCLUSIVE:前面包括,后面不包括。Spannable.SPAN_INCLUSIVE_INCLUSIVE:前后都包括。
3.常用设置
效果图
3.1 BackgroundColorSpan 背景色
SpannableString spanText =new SpannableString(" -- http://www.google.com");
spanText.setSpan(new BackgroundColorSpan(Color.GREEN),, spanText.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
mTVText.append("\n");
mTVText.append(spanText);
3.2 ClickableSpan 文本可点击,有点击事件
final SpannableString ss = new SpannableString("http://www.g.cn");
ClickableSpan click = new ClickableSpan() {
@Override
public void onClick(View widget) {
Snackbar snackbar = Snackbar.make(search, ss + "\t clicked",Snackbar.LENGTH_SHORT);
snackbar.show();
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
}
};
ss.setSpan(click,,ss.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
//下面代码是给TextView添加一个ClickableSpan
text.setMovementMethod(LinkMovementMethod.getInstance());//如果使用这个span的view不设置这个参数,没有点击事件
text.setHighlightColor(Color.TRANSPARENT); //设置点击后的颜色为透明,不然的高亮背景色
text.setText(ss);
//下面代码是给EditText添加一个ClickableSpan
Editable et = search.getText();
System.out.println(et);
search.setMovementMethod(LinkMovementMethod.getInstance());
et.insert(search.getSelectionStart(),ss);
System.out.println(et);
3.3 ForegroundColorSpan 文本颜色(前景色)
spanText = new SpannableString(" -- http://www.google.com");
spanText.setSpan(new ForegroundColorSpan(Color.BLUE),, spanText.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
mTVText.append("\n");
mTVText.append(spanText);
3.4 修饰效果,如模糊(BlurMaskFilter)、浮雕(EmbossMaskFilter)
spanText = new SpannableString("MaskFilterSpan -- http://orgcent.com");
int length = spanText.length();
//模糊(BlurMaskFilter)
MaskFilterSpan maskFilterSpan = new MaskFilterSpan(new BlurMaskFilter(, Blur.OUTER));
spanText.setSpan(maskFilterSpan, , length - , Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
//浮雕(EmbossMaskFilter)
maskFilterSpan = new MaskFilterSpan(new EmbossMaskFilter(new float[]{, , }, 1.5f, , ));
spanText.setSpan(maskFilterSpan, length - , length, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
mTVText.append("\n");
mTVText.append(spanText);
PS:从上图看,浮雕效果不明显。把字体设置大点后可以看得清晰些。需要其他效果可以继承MaskFilter来自定义。
3.5 MetricAffectingSpan 父类
一般不用
3.6 RasterizerSpan 光栅效果
spanText = new SpannableString("StrikethroughSpan");
spanText.setSpan(new StrikethroughSpan(), , , Spannable.
SPAN_INCLUSIVE_EXCLUSIVE);
mTVText.append("\n");
mTVText.append(spanText);
PS:暂不清楚,效果不明显。
3.7 StrikethroughSpan 删除线
spanText = new SpannableString("StrikethroughSpan");
spanText.setSpan(new StrikethroughSpan(),,, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
mTVText.append("\n");
mTVText.append(spanText);
3.8 UnderlineSpan 下划线
spanText = new SpannableString("UnderlineSpan");
spanText.setSpan(new UnderlineSpan(), , spanText.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
mTVText.append("\n");
mTVText.append(spanText);
3.9 SuggestionSpan 占位符
相当于占位符,一般用在EditText输入框中。当双击此文本时,会弹出提示框选择一些建议(推荐的)文字,选中的文本将替换此占位符。在输入法上用的较多。
PS:API 14新增,暂无示例。
3.10 AbsoluteSizeSpan 绝对大小(文本字体)
spanText = new SpannableString("AbsoluteSizeSpan");
spanText.setSpan(new AbsoluteSizeSpan(, true), , spanText.length(),Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
mTVText.append("\n");
mTVText.append(spanText);
3.11 DynamicDrawableSpan 设置图片,基于文本基线或底部对齐。
DynamicDrawableSpan drawableSpan =
new DynamicDrawableSpan(DynamicDrawableSpan.ALIGN_BASELINE) {
@Override
public Drawable getDrawable() {
Drawable d = getResources().getDrawable(R.drawable.ic_launcher);
d.setBounds(, , , );
return d;
}
};
DynamicDrawableSpan drawableSpan2 = new DynamicDrawableSpan(
DynamicDrawableSpan.ALIGN_BOTTOM) {
@Override
public Drawable getDrawable() {
Drawable d = getResources().getDrawable(R.drawable.ic_launcher);
d.setBounds(, , , );
return d;
}
};
spanText.setSpan(drawableSpan, , , Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
spanText.setSpan(drawableSpan2, , , Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
mTVText.append("\n");
mTVText.append(spanText);
PS:左边图片基于基线对齐,右边图片基于底部对齐。其它示例如下:
//构造一个内容只有一个图片的 SpannableString
SpannableString dynamic = new SpannableString(" "); //构造DynamicDrawableSpan,注意其中的参数 ALIGN_BASELINE让插入的图片最底部基于文本的基线对齐;
//ALIGN_BOTTOM 基于EditText的底部对齐。。
DynamicDrawableSpan dynamicDrawableSpan = new DynamicDrawableSpan(DynamicDrawableSpan.ALIGN_BASELINE) {
@Override
public Drawable getDrawable() {
Drawable d = getResources().getDrawable(R.drawable.indicator_input_error);
d.setBounds(, , , );
return d;
}
};
//注意要两边都不包括,就是只把“ ”换成图片
dynamic.setSpan(dynamicDrawableSpan, ,, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); //获取EditText中的内容
Editable et = imageEdit.getText();
//把新构造的只有一个图片的SpannableString插入到EditText中
int start = imageEdit.getSelectionStart();
et.insert(start, dynamic);
3.12 ImageSpan 图片
spanText = new SpannableString("ImageSpan");
Drawable d = getResources().getDrawable(R.drawable.ic_launcher);
d.setBounds(, , , );
spanText.setSpan(new ImageSpan(d), , , Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
mTVText.append("\n");
mTVText.append(spanText);
PS:和DynamicDrawableSpan差别不大
上述代码是把"ImageSpan"中的g应用了图片特效。也可以在文本中只插入一个图片特效。并且其它view得到这个新文本后也能正常显示图片,如下:
//insertImg是个EditText,假设当前已经输入abc
//打印插入图片之前的文本,这里输出: abc
System.out.println(imageEdit.getText()); //构造一个内容只有一个图片的 SpannableString
SpannableString imgSpannable = new SpannableString(" ");
//得到图片
Drawable drawable = getResources().getDrawable(R.drawable.indicator_input_error);
drawable.setBounds(, , drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); //构造ImageSpan
ImageSpan span = new ImageSpan(drawable);
//注意要两边都不包括,就是只把“ ”换成图片
imgSpannable.setSpan(span, ,, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); //获取EditText中的内容
Editable et = imageEdit.getText();
//把新构造的只有一个图片的SpannableString插入到EditText中
int start = imageEdit.getSelectionStart();
et.insert(start, imgSpannable); //打印插入图片之后的文本,这里会输出: ab c
System.out.println(imageEdit.getText());
//其中ab与c之间的空白就是插入的图片。
//其它view可以直接使用这个文本并能正确显示“ab图片c”,不用我们解析,把其中的空格替换成图片。
3.13 RelativeSizeSpan 相对大小(文本字体)
spanText = new SpannableString("RelativeSizeSpan");
//参数proportion:比例大小
spanText.setSpan(new RelativeSizeSpan(2.5f), , ,Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
mTVText.append("\n");
mTVText.append(spanText);
PS:相对大小的比例是基于当前文本字体大小
3.14 ReplacementSpan 父类
一般不用
3.15 ScaleXSpan 基于x轴缩放
spanText = new SpannableString("ScaleXSpan -- 萝卜白菜的博客");
//参数proportion:比例大小
spanText.setSpan(new ScaleXSpan(3.8f), , , Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
mTVText.append("\n");
mTVText.append(spanText);
3.16 StyleSpan 字体样式:粗体、斜体等
spanText = new SpannableString("StyleSpan -- 萝卜白菜的博客");
//Typeface.BOLD_ITALIC:粗体+斜体
spanText.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), , ,
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
mTVText.append("\n");
mTVText.append(spanText);
3.17 SubscriptSpan 下标(数学公式会用到)
spanText = new SpannableString("SubscriptSpan -- 萝卜白菜的博客");
spanText.setSpan(new SubscriptSpan(), , , Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
mTVText.append("\n");
mTVText.append(spanText);
3.18 SuperscriptSpan 上标(数学公式会用到)
spanText = new SpannableString("SuperscriptSpan -- 萝卜白菜的博客");
spanText.setSpan(new SuperscriptSpan(), , , Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
mTVText.append("\n");
mTVText.append(spanText);
3.19 TextAppearanceSpan 文本外貌(包括字体、大小、样式和颜色)
spanText = new SpannableString("TextAppearanceSpan -- 萝卜白菜的博客");
//若需自定义TextAppearance,可以在系统样式上进行修改
spanText.setSpan(new TextAppearanceSpan(this, android.R.style.TextAppearance_Medium), , , Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
mTVText.append("\n");
mTVText.append(spanText);
PS:系统还提供了相关值TextAppearance_Small, TextAppearance_Large等。如有需要可在以上样式基础上修改。
3.20 TypefaceSpan 文本字体
spanText = new SpannableString("TypefaceSpan -- 萝卜白菜的博客");
//若需使用自定义字体,可能要重写类TypefaceSpan
spanText.setSpan(new TypefaceSpan("monospace"), , ,Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
mTVText.append("\n");
mTVText.append(spanText);
PS:关于自定义字体的设置,后面将介绍如何使用
3.21 URLSpan 文本超链接
spanText = new SpannableString("URLSpan -- 萝卜白菜的博客");
spanText.setSpan(new URLSpan("http://orgcent.com"), , spanText.length(),Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
mTVText.append("\n");
mTVText.append(spanText);
//让URLSpan可以点击
mTVText.setMovementMethod(new LinkMovementMethod());
PS:
1、LinkMovementMethod是继承了ScrollingMovementMethod类,这个类用来实现TextView在没有使用标签也可以实现滚动效果。
2、若想实现无下划线的超链接,查看Android使用TextView实现无下划线超链接
*像word一样编辑复杂的文本:SpannableString 样式详介的更多相关文章
- PDF编辑:pdfFactory文本备注功能详解
除了word的doc文件外,PDF也是我们经常接触到的文件格式,经常需要在pdf文件上进行编辑与修改,或者给内容做提示和备注. 文件的文本备注功能可以用pdfFactory来进行,编辑打印PDF一条龙 ...
- C# 在word中查找及替换文本
C# 在word中查找及替换文本 在处理word文档时,很多人都会用到查找和替换功能.尤其是在处理庞大的word文档的时候,Microsoft word的查找替换功能就变得尤为重要,它不仅能让我们轻易 ...
- word在线编辑\生成图片(包含截图与合并)
1.业务原因 word编辑后的文章复制到html编辑器(fck等)会发生排版错乱的情况,于是混沌了.需要有一个新的方法来终结,于是产生了word能不能在线编辑,后台保存,前台显示灯一系列问题. 2.首 ...
- word中编辑论文公式对齐问题
这里只说在word中编辑公式时,公式居中,编号右对齐的情况. 在编辑公式时,我平时就是右对齐,然后通过敲击空格键进行公式的居中,然而这样并不美观.所以接下来学习一下: 1)首先打开视图-->标尺 ...
- MFC控件编程之 按钮编辑框.静态文本的使用,以及访问控件的七种方法.
MFC控件编程之 按钮编辑框.静态文本的使用以及访问控件的七种方法. 一丶按钮.静态文本的通用属性. 他们都有一个属性.就是可以输入标题内容.以及可以自定义控件ID. 创建一个MFC Dlg对话框. ...
- MFC_2.2 编辑框和文本控件
编辑框和文本控件 1.拖控件 2.绑定变量.用户名密码编辑框控件类型.取名字.用户协议用值类型,默认CString. 设置属性.用户类型.选择mustiline TRUE. AOTO HScroll ...
- 将 PDF 论文的公式截图后转成 Word 可编辑公式(23)
1. 问题 如何将PDF论文的公式截图后直接转成Word可编辑的公式? 2. 方法步骤 1.下载mathpix 2.使用mathpix截取公式,并生成LATEX 公式: 3.下载LaTeX转Word插 ...
- 如何在Word中批量选中特定文本
如何在Word中批量选中特定文本 举个例子,我们对如下文本进行操作,将文本中所有的“1111111”标红,所有的“2222222”标绿,所有的“3333333”标蓝 在Word中找到“查找”下的“高级 ...
- Delphi TMemo 可以显示、编辑多行文本
多行编辑框组件(TMemo)TMemo组件可以显示.编辑多行文本,是一个标准的Windows多行编辑组件.对一些比较多的文本内容可以利用TMemo组件来显示.编辑. 1.TMemo组件的典型用法 TM ...
随机推荐
- C预处理,条件编译
预处理是指在编译器之前运行,常以“#”开头 包含3个方面的内容: 1)宏定义与宏替换 2)文件包含 3)条件编译 宏定义与宏替换: 宏名一般大写,替换发生在编译之前,且是机械替换,不做语法检查,也不分 ...
- 编译时IOS Device 无法选择的情况
问题描述:当你项目开发环境Xocode版本高于你本地Xocode 编译版本时,在本地运行会出现如下错误: 解决: 重写调整Deloyment Target 的版本 注:还有一种情况会出现如上错误,并 ...
- linux第四周作业
一.用户态内核态与中断 1.库函数把内核调用封装起来. 2.区分内核态和用户态是为了让系统更稳定.Linux里吧用户态定位3级,把内核态定位0级. 3.中断处理就是从用户态进入内核态的主要方法,系统调 ...
- OC内存管理 @property的增强
涉及到内存管理,只读,多线程等很多功能时,setter和getter方法也就没那么简单了:当然@property依然强大,很好用: 1:内存管理相关参数: *:retain: (如果是oc对象类型) ...
- app进入后台申请10分钟活跃时间-b
IOS允许长时间在后台运行的情况有7种: audio VoIP GPS 下载新闻 和其它附属硬件进行通讯时 使用蓝牙进行通讯时 使用蓝牙共享数据时 除以上情况,程序退出时可能设置短暂运行10分钟 让程 ...
- 剑指offer--面试题11
题目:求数值的整数次方,不考虑大数值情况 即实现函数:double Power(double base, int exponent) 自己所写代码如下: #include "stdafx.h ...
- [C/CPP系列知识] 那些程序C语言可以编译通过但C++无法编译成功 Write a C program that won’t compile in C++
http://www.geeksforgeeks.org/write-c-program-wont-compiler-c/ 1) C++中在函数声明之前调用一个函数会引发错误,但是在C中有可能可以. ...
- 【系统Configmachine.config与自己的应用程序的App.config/Web.Config配置节点重复】解决方法
自己的应用程序的App.config或Web.Config文件中与系统的C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Configmachine.co ...
- spring @resource @ Autowired
Spring中什么时候用@Resource,什么时候用@service 当你需要定义某个类为一个bean,则在这个类的类名前一行使用@Service("XXX"),就相当于讲这个类 ...
- unity3d结合轮廓显示,实现完整的框选目标(附Demo代码)
原地址:http://dong2008hong.blog.163.com/blog/static/469688272013111554511948/ 在unity里实现,其实很简单,因为有两个前提:1 ...