博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpannableString--让你的TextView装逼
阅读量:2232 次
发布时间:2019-05-09

本文共 5636 字,大约阅读时间需要 18 分钟。

TextView 应该是Android 中使用频率最高的控件之一,其重要性不言而喻

在平时的开发中,对于TextView的使用方法无非就是在layout 中设置一下布局、样式、颜色等,要是需要进行改变,丢到handler里

复杂一点的可以引入字体文件,通过资源进行设置

但是如果要在一定的范围内改变字体的样式怎么解决?拆分String,用两个TextView?

如果要让TextView实现类似于超链接的跳转功能怎么解决?添加监听事件,配合Intent使用?

再牛逼点,如果我要你TextView 显示图片,咋整? 啥?强转会报错?

现在,就正式请出今天的主角,SpannableString和SpannableStringBuilder

先说说二者的区别, SpannableString的长度固定,而SpannableStringBuilder的长度是可以改变的

本文着重就以SpannableString为例,至于SpannableStringBuilder的使用,我相信每个开发人员都懂得触类旁通,就不多介绍了

首先,我们先看下SpannableString的源码

public class SpannableStringextends SpannableStringInternalimplements CharSequence, GetChars, Spannable{    public SpannableString(CharSequence source) {        super(source, 0, source.length());    }    private SpannableString(CharSequence source, int start, int end) {        super(source, start, end);    }    public static SpannableString valueOf(CharSequence source) {        if (source instanceof SpannableString) {            return (SpannableString) source;        } else {            return new SpannableString(source);        }    }    public void setSpan(Object what, int start, int end, int flags) {        super.setSpan(what, start, end, flags);    }    public void removeSpan(Object what) {        super.removeSpan(what);    }    public final CharSequence subSequence(int start, int end) {        return new SpannableString(this, start, end);    }}
继承了抽象类SpannableStringInternal,和三个接口CharSequence, GetChars, Spannable

构造函数

public SpannableString(CharSequence source) {

        super(source, 0, source.length());
    }

参数就不多解释了

再看看setSpan方法

public void setSpan(Object what, int start, int end, int flags) {        super.setSpan(what, start, end, flags);    }

传入的参数有四个,这里解释下

/*** what  字体设置的格式* start 所设置字体的起始下标* end   所设置结束下标* flags 下标取值标志,取值:* Spanned.SPAN_INCLUSIVE_EXCLUSIVE  从起始下标到结束下标,包括起始下标* Spanned.SPAN_INCLUSIVE_INCLUSIVE  从起始下标到结束下标,同时包括起始下标和结束下标* Spanned.SPAN_EXCLUSIVE_EXCLUSIVE  从起始下标到终了下标,但都不包括起始下标和结束下标* Spanned.SPAN_EXCLUSIVE_INCLUSIVE  从起始下标到结束下标,包括结束下标**/
有点拗口,但就是高中数学里交集并集的关系

如果实在不行,就看看我这边的栗子

package com.example.textviewdemo;import android.app.Activity;import android.graphics.Color;import android.os.Bundle;import android.text.Spannable;import android.text.SpannableString;import android.text.style.ForegroundColorSpan;import android.widget.EditText;public class MainActivity extends Activity {	/**	* what  字体设置的格式	* start 所设置字体的起始下标	* end   所设置结束下标	* flags 下标取值标志,取值:	* Spanned.SPAN_INCLUSIVE_EXCLUSIVE  从起始下标到结束下标,包括起始下标	* Spanned.SPAN_INCLUSIVE_INCLUSIVE  从起始下标到结束下标,同时包括起始下标和结束下标	* Spanned.SPAN_EXCLUSIVE_EXCLUSIVE  从起始下标到终了下标,但都不包括起始下标和结束下标	* Spanned.SPAN_EXCLUSIVE_INCLUSIVE  从起始下标到结束下标,包括结束下标	**/	private EditText mEt1,mEt2,mEt3,mEt4;	@Override	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(R.layout.activity_main);		initView();	}	private void initView(){		mEt1 = (EditText)findViewById(R.id.et1);		mEt2 = (EditText)findViewById(R.id.et2);		mEt3 = (EditText)findViewById(R.id.et3);		mEt4 = (EditText)findViewById(R.id.et4);		        //构造SpannableString          SpannableString spanString = new SpannableString("天王盖地虎宝塔镇河妖");            SpannableString spanString2 = new SpannableString("天王盖地虎宝塔镇河妖");        SpannableString spanString3 = new SpannableString("天王盖地虎宝塔镇河妖");        SpannableString spanString4 = new SpannableString("天王盖地虎宝塔镇河妖");       //用于改变字体颜色的ForegroundColorSpan        ForegroundColorSpan span = new ForegroundColorSpan(Color.BLUE);            //设定范围,传入不同的flag        spanString.setSpan(span, 1, 3, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);            spanString2.setSpan(span, 1, 3, Spannable.SPAN_INCLUSIVE_INCLUSIVE);            spanString3.setSpan(span, 1, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);            spanString4.setSpan(span, 1, 3, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);            //在不同的EditText中显示        mEt1.setText(spanString);          mEt2.setText(spanString2);          mEt3.setText(spanString3);          mEt4.setText(spanString4);  	}}
然后分别在前后插入字符,效果如下

 

其他设置

上面的那颗栗子用到了设置颜色的类,但仅仅只能设置颜色,如何装逼?

//改变字体背景色的span        BackgroundColorSpan colorSpan = new BackgroundColorSpan(Color.BLUE);
//改变字体大小的span,传入一个int 值        AbsoluteSizeSpan sizeSpan = new AbsoluteSizeSpan(16);           //设置文字相对大小的span,传入一个float,以原有字体的大小为基础设置倍数        RelativeSizeSpan rSizeSpan = new RelativeSizeSpan(1.5f);        //一些文本标志,以下划线为例        UnderlineSpan lineSpan = new UnderlineSpan();
当然,除了这些,还有删除线(StrikethroughSpan) 文本样式(StyleSpan)等其他样式

上例的运行结果如图

介绍完样式使用,接下来隆重介绍两种更有逼格的用法

首先,试试在字段中加入一个超链接吧,代码如下

//超链接文本        SpannableString spanString6 = new SpannableString("天王盖地虎宝塔镇河妖");        URLSpan urlSpan = new URLSpan("http://www.baidu.com");        spanString6.setSpan(urlSpan,1, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);        mTv1.setMovementMethod(LinkMovementMethod.getInstance());        mTv1.setHighlightColor(Color.BLUE);        mTv1.setText(spanString6);
运行效果:

点击后自动跳转页面,不用给TextView 添加监听事件,是不是很酷

你以为就这些功能?

前些天在倒腾聊天页面,要实现图片、文字的发送,文字用TextView 加到Item中即可,但是要在ListView 中显示图片就有些麻烦了。

我最开始的思路是在一个布局里同时存放ImageView 和TextView ,然后根据类型进行判断,将其设置为VISILIABLE 和GONE

但是这种方法使得适配器的代码过于冗长,而且findViewById 的开销有比较大,这才想到了也许可以用SpannableString来结局这个问题

废话少说,上代码

SpannableString spanString7 = new SpannableString("天王盖地虎宝塔镇河妖");        Drawable drawable = getResources().getDrawable(R.drawable.ic_launcher);        //设置图片大小        drawable.setBounds(0, 0, 66, 66);        ImageSpan imageSpan = new ImageSpan(drawable);        spanString7.setSpan(imageSpan, 0, spanString7.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);        mTv2.setText(spanString7);

上述所有的例子显示都如下图所示,顺便提一下聊天界面中Item 的思路,将接收到的图片保存至本地后将url保存到List中,首先判断数据的类型,如果是为图片,则直接将TextView 设置成该地址所对应的图片,将其显示出来,怎么样,是不是又方便又有逼格?

你可能感兴趣的文章
Maven出错-Missing artifact org.apache.openejb:openejb-core:jar:4.1.0-SNAPSHOT:test
查看>>
dubbo配置文件xml校验报错
查看>>
eclipse生成export生成jar详解
查看>>
oracle 模糊查询忽略大小写
查看>>
Java项目导出可运行的jar文件
查看>>
Java文件夹操作,判断多级路径是否存在,不存在就创建(包括windows和linux下的路径字符分析),兼容Windows和Linux
查看>>
JAVA读取PROPERTIES配置文件
查看>>
Linux中执行shell脚本的4种方法总结
查看>>
BufferedInputStream(缓冲输入流)详解
查看>>
修改linux文件权限命令:chmod
查看>>
Linux vi/vim编辑器常用命令与用法总结
查看>>
如何使用Git Bash Here,将本地项目传到github上
查看>>
eclipse git控件操作 回退到历史提交 重置 删除(撤销)历史的某次提交
查看>>
Oracle | 给表和字段添加注释
查看>>
java比较日期大小及日期与字符串的转换【SimpleDateFormat操作实例】
查看>>
Oracle新表使用序列(sequence)作为插入值,初始值不是第一个,oraclesequence
查看>>
java中System.exit()方法
查看>>
在hbase shell中过滤器的简单使用
查看>>
java静态方法和实例方法
查看>>
java多线程并发去调用一个类的静态方法,会有问题吗?
查看>>