*像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 ...
随机推荐
- mysql 连接语句
在 SELECT 语句中,如果 FROM 子句引用了多个表源或视图,可以使用 JOIN 指示指定的联接操作应在指定的表源或视图之间执行. 一.交叉联接:CROSS JOIN 交叉联接将执行一个叉积(迪 ...
- Http请求和响应应用
//以下载方式打开资源 public void test4(HttpServletResponse response) throws IOException { response.setHeader( ...
- 使用ASP.NET注册工具aspnet_regiis.exe注册IIS
该工具的名称为aspnet_regiis.exe,在32位机上,该工具存在于C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727,在64位机中“Framework ...
- 简单易用的导出文件(Excel、word等各种格式)的方法
以前学习过NPOI导出数据到Excel中,代码较长,不易记忆.工作中,看到了其他同事写的代码,研究了一下,贴出来,共同学习. 使用这种方式,不仅可以设置表格的样式,而且代码简洁. 首先,在后台中通过S ...
- Visual Studio Code asp.net 5环境搭建技能Get
启动准备阶段 预热 1 VS Code 官方地址:https://www.visualstudio.com/en-us/products/code-vs.aspx 2 安装Node.js :https ...
- Fixing:insert_modules not found
搞linux的最怕的就是panic.满屏的报错不知头绪,百度出来的还都是抄来抄去的垃圾. 我遇到的错误已经解决,所以不想再看到报错了..google出来两个没有上下文的文本,因为和他们差不多,在下面贴 ...
- angular入门系列教程2
主题: 本篇主要介绍下angular里的一些概念,并且在咱们的小应用上加上点料.. 概念(大概了解即可,代码中遇到的会有详细注释): 模板:动态模板,是动态的,直接去处理DOM的,而不是通过处理字符串 ...
- 20160729noip模拟赛zld
首先显然有多少个奇数,就有多少个回文串是最优的(没有奇数时构造一个回文串 然后有了k个“核心”,把剩下的字符顺序安排到这些的两侧,最后最短的回文串长度就是答案 #include<map> ...
- Leetcode#143 Reorder List
原题地址 先把链表分割成前后两半,然后交叉融合 实践证明,凡是链表相关的题目,都应该当成工程类题目做,局部变量.功能函数什么的随便整,代码长了没关系,关键是清楚,不容易出错. 代码: ListNode ...
- HTTP/2 对 Web 性能的影响(上)
一.前言 HTTP/2 于 2015 年 5 月正式推出.自诞生以来,它就一直在影响着网络性能最佳实践.在本篇文章中,我们将讨论 HTTP/2 的二进制帧.延迟削减.潜在利弊以及相应的应对措施. 超文 ...