转:工具类之SpannableStringUtils(相信你会爱上它)
这个工具类真是构思了良久才设计出来,采用了建造者模式,然后你们就可以用链式调用了,talk is cheap, let me show the demo.


有没有心动一下哈,下面就让老司机为你们开路。
站点
- SpannableString相关工具类→SpannableStringUtils.java→Demo
getBuilder : 获取建造者
setFlag : 设置标识
setForegroundColor: 设置前景色
setBackgroundColor: 设置背景色
setQuoteColor : 设置引用线的颜色
setLeadingMargin : 设置缩进
setBullet : 设置列表标记
setProportion : 设置字体比例
setXProportion : 设置字体横向比例
setStrikethrough : 设置删除线
setUnderline : 设置下划线
setSuperscript : 设置上标
setSubscript : 设置下标
setBold : 设置粗体
setItalic : 设置斜体
setBoldItalic : 设置粗斜体
setFontFamily : 设置字体
setAlign : 设置对齐
setBitmap : 设置图片
setDrawable : 设置图片
setUri : 设置图片
setResourceId : 设置图片
setClickSpan : 设置点击事件
setUrl : 设置超链接
setBlur : 设置模糊
append : 追加样式字符串
create : 创建样式字符串
具体路线
package com.blankj.utilcode.utils;
import android.graphics.Bitmap;
import android.graphics.BlurMaskFilter;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.annotation.ColorInt;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.Layout.Alignment;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.AlignmentSpan;
import android.text.style.BackgroundColorSpan;
import android.text.style.BulletSpan;
import android.text.style.ClickableSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.ImageSpan;
import android.text.style.LeadingMarginSpan;
import android.text.style.MaskFilterSpan;
import android.text.style.QuoteSpan;
import android.text.style.RelativeSizeSpan;
import android.text.style.ScaleXSpan;
import android.text.style.StrikethroughSpan;
import android.text.style.StyleSpan;
import android.text.style.SubscriptSpan;
import android.text.style.SuperscriptSpan;
import android.text.style.TypefaceSpan;
import android.text.style.URLSpan;
import android.text.style.UnderlineSpan;
import static android.graphics.BlurMaskFilter.Blur;
/**
* <pre>
* author: Blankj
* blog : http://blankj.com
* time : 16/12/13
* desc : SpannableString相关工具类
* </pre>
*/
public class SpannableStringUtils {
private SpannableStringUtils() {
throw new UnsupportedOperationException("u can't instantiate me...");
}
/**
* 获取建造者
*
* @return {@link Builder}
*/
public static Builder getBuilder(@NonNull CharSequence text) {
return new Builder(text);
}
public static class Builder {
private int defaultValue = 0x12000000;
private CharSequence text;
private int flag;
@ColorInt
private int foregroundColor;
@ColorInt
private int backgroundColor;
@ColorInt
private int quoteColor;
private boolean isLeadingMargin;
private int first;
private int rest;
private boolean isBullet;
private int gapWidth;
private int bulletColor;
private float proportion;
private float xProportion;
private boolean isStrikethrough;
private boolean isUnderline;
private boolean isSuperscript;
private boolean isSubscript;
private boolean isBold;
private boolean isItalic;
private boolean isBoldItalic;
private String fontFamily;
private Alignment align;
private boolean imageIsBitmap;
private Bitmap bitmap;
private boolean imageIsDrawable;
private Drawable drawable;
private boolean imageIsUri;
private Uri uri;
private boolean imageIsResourceId;
@DrawableRes
private int resourceId;
private ClickableSpan clickSpan;
private String url;
private boolean isBlur;
private float radius;
private Blur style;
private SpannableStringBuilder mBuilder;
private Builder(@NonNull CharSequence text) {
this.text = text;
flag = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
foregroundColor = defaultValue;
backgroundColor = defaultValue;
quoteColor = defaultValue;
proportion = -1;
xProportion = -1;
mBuilder = new SpannableStringBuilder();
}
/**
* 设置标识
*
* @param flag <ul>
* <li>{@link Spanned#SPAN_INCLUSIVE_EXCLUSIVE}</li>
* <li>{@link Spanned#SPAN_INCLUSIVE_INCLUSIVE}</li>
* <li>{@link Spanned#SPAN_EXCLUSIVE_EXCLUSIVE}</li>
* <li>{@link Spanned#SPAN_EXCLUSIVE_INCLUSIVE}</li>
* </ul>
* @return {@link Builder}
*/
public Builder setFlag(int flag) {
this.flag = flag;
return this;
}
/**
* 设置前景色
*
* @param color 前景色
* @return {@link Builder}
*/
public Builder setForegroundColor(@ColorInt int color) {
this.foregroundColor = color;
return this;
}
/**
* 设置背景色
*
* @param color 背景色
* @return {@link Builder}
*/
public Builder setBackgroundColor(@ColorInt int color) {
this.backgroundColor = color;
return this;
}
/**
* 设置引用线的颜色
*
* @param color 引用线的颜色
* @return {@link Builder}
*/
public Builder setQuoteColor(@ColorInt int color) {
this.quoteColor = color;
return this;
}
/**
* 设置缩进
*
* @param first 首行缩进
* @param rest 剩余行缩进
* @return {@link Builder}
*/
public Builder setLeadingMargin(int first, int rest) {
this.first = first;
this.rest = rest;
isLeadingMargin = true;
return this;
}
/**
* 设置列表标记
*
* @param gapWidth 列表标记和文字间距离
* @param color 列表标记的颜色
* @return {@link Builder}
*/
public Builder setBullet(int gapWidth, int color) {
this.gapWidth = gapWidth;
bulletColor = color;
isBullet = true;
return this;
}
/**
* 设置字体比例
*
* @param proportion 比例
* @return {@link Builder}
*/
public Builder setProportion(float proportion) {
this.proportion = proportion;
return this;
}
/**
* 设置字体横向比例
*
* @param proportion 比例
* @return {@link Builder}
*/
public Builder setXProportion(float proportion) {
this.xProportion = proportion;
return this;
}
/**
* 设置删除线
*
* @return {@link Builder}
*/
public Builder setStrikethrough() {
this.isStrikethrough = true;
return this;
}
/**
* 设置下划线
*
* @return {@link Builder}
*/
public Builder setUnderline() {
this.isUnderline = true;
return this;
}
/**
* 设置上标
*
* @return {@link Builder}
*/
public Builder setSuperscript() {
this.isSuperscript = true;
return this;
}
/**
* 设置下标
*
* @return {@link Builder}
*/
public Builder setSubscript() {
this.isSubscript = true;
return this;
}
/**
* 设置粗体
*
* @return {@link Builder}
*/
public Builder setBold() {
isBold = true;
return this;
}
/**
* 设置斜体
*
* @return {@link Builder}
*/
public Builder setItalic() {
isItalic = true;
return this;
}
/**
* 设置粗斜体
*
* @return {@link Builder}
*/
public Builder setBoldItalic() {
isBoldItalic = true;
return this;
}
/**
* 设置字体
*
* @param fontFamily 字体
* <ul>
* <li>monospace</li>
* <li>serif</li>
* <li>sans-serif</li>
* </ul>
* @return {@link Builder}
*/
public Builder setFontFamily(@Nullable String fontFamily) {
this.fontFamily = fontFamily;
return this;
}
/**
* 设置对齐
* <ul>
* <li>{@link Alignment#ALIGN_NORMAL}正常</li>
* <li>{@link Alignment#ALIGN_OPPOSITE}相反</li>
* <li>{@link Alignment#ALIGN_CENTER}居中</li>
* </ul>
*
* @return {@link Builder}
*/
public Builder setAlign(@Nullable Alignment align) {
this.align = align;
return this;
}
/**
* 设置图片
*
* @param bitmap 图片位图
* @return {@link Builder}
*/
public Builder setBitmap(@NonNull Bitmap bitmap) {
this.bitmap = bitmap;
imageIsBitmap = true;
return this;
}
/**
* 设置图片
*
* @param drawable 图片资源
* @return {@link Builder}
*/
public Builder setDrawable(@NonNull Drawable drawable) {
this.drawable = drawable;
imageIsDrawable = true;
return this;
}
/**
* 设置图片
*
* @param uri 图片uri
* @return {@link Builder}
*/
public Builder setUri(@NonNull Uri uri) {
this.uri = uri;
imageIsUri = true;
return this;
}
/**
* 设置图片
*
* @param resourceId 图片资源id
* @return {@link Builder}
*/
public Builder setResourceId(@DrawableRes int resourceId) {
this.resourceId = resourceId;
imageIsResourceId = true;
return this;
}
/**
* 设置点击事件
* <p>需添加view.setMovementMethod(LinkMovementMethod.getInstance())</p>
* @param clickSpan 点击事件
* @return {@link Builder}
*/
public Builder setClickSpan(@NonNull ClickableSpan clickSpan) {
this.clickSpan = clickSpan;
return this;
}
/**
* 设置超链接
* <p>需添加view.setMovementMethod(LinkMovementMethod.getInstance())</p>
*
* @param url 超链接
* @return {@link Builder}
*/
public Builder setUrl(@NonNull String url) {
this.url = url;
return this;
}
/**
* 设置模糊
* <p>尚存bug,其他地方存在相同的字体的话,相同字体出现在之前的话那么就不会模糊,出现在之后的话那会一起模糊</p>
* <p>推荐还是把所有字体都模糊这样使用</p>
*
* @param radius 模糊半径(需大于0)
* @param style 模糊样式<ul>
* <li>{@link Blur#NORMAL}</li>
* <li>{@link Blur#SOLID}</li>
* <li>{@link Blur#OUTER}</li>
* <li>{@link Blur#INNER}</li>
* </ul>
* @return {@link Builder}
*/
public Builder setBlur(float radius, Blur style) {
this.radius = radius;
this.style = style;
this.isBlur = true;
return this;
}
/**
* 追加样式字符串
*
* @param text 样式字符串文本
* @return {@link Builder}
*/
public Builder append(@NonNull CharSequence text) {
setSpan();
this.text = text;
return this;
}
/**
* 创建样式字符串
*
* @return 样式字符串
*/
public SpannableStringBuilder create() {
setSpan();
return mBuilder;
}
/**
* 设置样式
*/
private void setSpan() {
int start = mBuilder.length();
mBuilder.append(this.text);
int end = mBuilder.length();
if (foregroundColor != defaultValue) {
mBuilder.setSpan(new ForegroundColorSpan(foregroundColor), start, end, flag);
foregroundColor = defaultValue;
}
if (backgroundColor != defaultValue) {
mBuilder.setSpan(new BackgroundColorSpan(backgroundColor), start, end, flag);
backgroundColor = defaultValue;
}
if (isLeadingMargin) {
mBuilder.setSpan(new LeadingMarginSpan.Standard(first, rest), start, end, flag);
isLeadingMargin = false;
}
if (quoteColor != defaultValue) {
mBuilder.setSpan(new QuoteSpan(quoteColor), start, end, 0);
quoteColor = defaultValue;
}
if (isBullet) {
mBuilder.setSpan(new BulletSpan(gapWidth, bulletColor), start, end, 0);
isBullet = false;
}
if (proportion != -1) {
mBuilder.setSpan(new RelativeSizeSpan(proportion), start, end, flag);
proportion = -1;
}
if (xProportion != -1) {
mBuilder.setSpan(new ScaleXSpan(xProportion), start, end, flag);
xProportion = -1;
}
if (isStrikethrough) {
mBuilder.setSpan(new StrikethroughSpan(), start, end, flag);
isStrikethrough = false;
}
if (isUnderline) {
mBuilder.setSpan(new UnderlineSpan(), start, end, flag);
isUnderline = false;
}
if (isSuperscript) {
mBuilder.setSpan(new SuperscriptSpan(), start, end, flag);
isSuperscript = false;
}
if (isSubscript) {
mBuilder.setSpan(new SubscriptSpan(), start, end, flag);
isSubscript = false;
}
if (isBold) {
mBuilder.setSpan(new StyleSpan(Typeface.BOLD), start, end, flag);
isBold = false;
}
if (isItalic) {
mBuilder.setSpan(new StyleSpan(Typeface.ITALIC), start, end, flag);
isItalic = false;
}
if (isBoldItalic) {
mBuilder.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), start, end, flag);
isBoldItalic = false;
}
if (fontFamily != null) {
mBuilder.setSpan(new TypefaceSpan(fontFamily), start, end, flag);
fontFamily = null;
}
if (align != null) {
mBuilder.setSpan(new AlignmentSpan.Standard(align), start, end, flag);
align = null;
}
if (imageIsBitmap || imageIsDrawable || imageIsUri || imageIsResourceId) {
if (imageIsBitmap) {
mBuilder.setSpan(new ImageSpan(Utils.context, bitmap), start, end, flag);
bitmap = null;
imageIsBitmap = false;
} else if (imageIsDrawable) {
mBuilder.setSpan(new ImageSpan(drawable), start, end, flag);
drawable = null;
imageIsDrawable = false;
} else if (imageIsUri) {
mBuilder.setSpan(new ImageSpan(Utils.context, uri), start, end, flag);
uri = null;
imageIsUri = false;
} else {
mBuilder.setSpan(new ImageSpan(Utils.context, resourceId), start, end, flag);
resourceId = 0;
imageIsResourceId = false;
}
}
if (clickSpan != null) {
mBuilder.setSpan(clickSpan, start, end, flag);
clickSpan = null;
}
if (url != null) {
mBuilder.setSpan(new URLSpan(url), start, end, flag);
url = null;
}
if (isBlur) {
mBuilder.setSpan(new MaskFilterSpan(new BlurMaskFilter(radius, style)), start, end, flag);
isBlur = false;
}
flag = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
}
}
}
终点站
为了能让乘客们调用地爽快与满意,我真是把能囊括的span都收纳过来了,终点站到了,如果对本次旅途满意的话,请给五星好评哦,毕竟老司机这次真的牺牲了很多时间与精力才换来这么一份精良的工具类,如果该工具类依赖其他工具类,都可以在我的Android开发人员不得不收集的代码(持续更新中)中找到。
原文链接:http://www.jianshu.com/p/960467ac56c8
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
转:工具类之SpannableStringUtils(相信你会爱上它)的更多相关文章
- Java基础Map接口+Collections工具类
1.Map中我们主要讲两个接口 HashMap 与 LinkedHashMap (1)其中LinkedHashMap是有序的 怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...
- Android—关于自定义对话框的工具类
开发中有很多地方会用到自定义对话框,为了避免不必要的城府代码,在此总结出一个工具类. 弹出对话框的地方很多,但是都大同小异,不同无非就是提示内容或者图片不同,下面这个类是将提示内容和图片放到了自定义函 ...
- [转]Java常用工具类集合
转自:http://blog.csdn.net/justdb/article/details/8653166 数据库连接工具类——仅仅获得连接对象 ConnDB.java package com.ut ...
- js常用工具类.
一些js的工具类 复制代码 /** * Created by sevennight on 15-1-31. * js常用工具类 */ /** * 方法作用:[格式化时间] * 使用方法 * 示例: * ...
- Guava库介绍之实用工具类
作者:Jack47 转载请保留作者和原文出处 欢迎关注我的微信公众账号程序员杰克,两边的文章会同步,也可以添加我的RSS订阅源. 本文是我写的Google开源的Java编程库Guava系列之一,主要介 ...
- Java程序员的日常—— Arrays工具类的使用
这个类在日常的开发中,还是非常常用的.今天就总结一下Arrays工具类的常用方法.最常用的就是asList,sort,toStream,equals,copyOf了.另外可以深入学习下Arrays的排 ...
- .net使用正则表达式校验、匹配字符工具类
开发程序离不开数据的校验,这里整理了一些数据的校验.匹配的方法: /// <summary> /// 字符(串)验证.匹配工具类 /// </summary> public c ...
- WebUtils-网络请求工具类
网络请求工具类,大幅代码借鉴aplipay. using System; using System.Collections.Generic; using System.IO; using System ...
- JAVA 日期格式工具类DateUtil.java
DateUtil.java package pers.kangxu.datautils.utils; import java.text.SimpleDateFormat; import java.ut ...
随机推荐
- 《JavaScript高级程序设计(第3版)》笔记-第1章-JavaScript 简介
PS:第一章内容实在不多,就把前些日子看过的记录整理了一下,先发上来. 1.1 JavaScript 简史 1.JavaScript诞生前期目的主要是为了处理这种简单的表单验证. 1.2 JavaSc ...
- javascript 技巧总结积累(正在积累中)
1.文本框焦点问题 onBlur:当失去输入焦点后产生该事件 onFocus:当输入获得焦点后,产生该文件 Onchange:当文字值改变时,产生该事件 Onselect:当文字加亮后,产生该文件 & ...
- MySQL练习-employees数据库(二)
department 部门表 dept_emp 部门员工任职期表(按部门&时期) dept_manager 部门经理任职期表(按时期) employees 员工详情表 salaries 员工薪 ...
- C++ vector容器find查询函数
vector< ); //查找1 if ( result == L.end( ) ) //没找到 cout << "No" << endl; else ...
- Xcode will continue when iPad is finished. "Could not find Developer Disk Image"
1: Xcode will continue when iPad is finished. 等待进度条读取完成即可: 2: xcode,安装新版本的iOS 的 xcode 支持文件 的路径: /ap ...
- AlloyTouch插件
1.老样子引入js <script src="js/transform.js"></script> <script src="js/allo ...
- 设计模式--原型模式Prototype(创建型)
一.原型模式 用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象.原型模式实现的关键就是实现Clone函数,还需要实现深拷贝. 二.UML类图 三.例子 //父类 class Resume ...
- 关于imageOrientation
用相机拍出来的照片都含有EXIF信息,UIImage的imageOrientation属性指的就是EXIF中的orientation信息.如果我们忽略orientation信心,而直接对照片进行想速处 ...
- 在ashx文件中制作验证码(使用session要继承IRequiresSessionState)
必须继承System.Web.SessionState.IRequiresSessionState接口,才能实现Session读写! System.Web.SessionState的一些接口 IRea ...
- 关于Vue vuex vux 文档
01. vue 链接 http://vuejs.org.cn/guide/ 02. vuex ----->>状态管理模块儿<<------- https://vuex.vue ...