1. 程式人生 > >工具類之SpannableStringUtils(相信你會愛上它)

工具類之SpannableStringUtils(相信你會愛上它)

這個工具類真是構思了良久才設計出來,採用了建造者模式,然後你們就可以用鏈式呼叫了,talk is cheap, let me show the demo.


demo
code

有沒有心動一下哈,下面就讓老司機為你們開路。

站點

  • 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都收納過來了,終點站到了,如果對本次旅途滿意的話,請給五星好評哦,畢竟老司機這次真的犧牲了很多時間與精力才換來這麼一份精良的工具類,如果該工具類依賴其他工具類,都可以在我的中找到。

相關推薦

工具SpannableStringUtils相信愛上

這個工具類真是構思了良久才設計出來,採用了建造者模式,然後你們就可以用鏈式呼叫了,talk is cheap, let me show the demo. demo code 有沒有心動一下哈,下面就讓老司機為你們開路。 站點 getBuilder

Android 常用開發工具 SPUtils SharedPreference 工具

開發過程中難免會遇到如持久儲存使用者資訊等需求,而由於資料量很少感覺使用 Sql 有些殺雞用牛刀的感覺也有些累贅。所以善於使用 SharedPreference 可以幫助我們在本地儲存一些資料量少,又使用很頻繁的東西。 SPUtils 一個可以幫助我們很簡潔的使用  Sha

Andorid開發工具——BitmapUtils壓縮圖片利器,告別oom,程式更快

最近開發的一個專案使用到了圖片載入上傳和儲存,由於是接受別人的做,也基本上做完了。但是程式已啟動到需要載入圖片上傳到伺服器的介面的時候記憶體就暴漲,雖然也沒有oom,估計舊點的手機肯定會爆,只要不啟動到圖片載入的頁面,記憶體基本上佔用只用20+mb,選擇圖片後達到了80兆。

java工具Excel檔案匯入、讀取資料支援xls、和xlsx

所需的jar包:poi的jar包儘量保持一致,不然會報版本不一致的錯誤下面是程式碼:package ReadExcel; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.

JAVA檔案工具——檔案寫入byte陣列、String方式、url寫入方式

/** * 將byte陣列寫入檔案 * * @param path * @param fileName * @param content * @throws I

Java工具Pattern和Matcher

我們在web開發時,肯定會涉及到資料校驗,這時正則表示式就必須用到了。在Java中有個Pattern型別對某種正則表示式編譯, ,然後使用Matcher類進行判斷是否匹配等。其中String類中也有match();使用。這個對Pattern和Matcher的簡單使用。 pa

網路請求工具OkHttp3封裝支援請求取消、非同步請求的執行緒切換

緊接著上篇說的任務2:非同步請求採用UI執行緒回撥方式。 首先採用Handler進行執行緒間的通訊,順便優化下回調方法,加入HttpInfo以做到工具類使用的滲透性。 在OkHttpUtil中宣告一個自定義的非同步回撥介面,該介面對網路請求介面進行了封裝,使同步、非同步請求

Java並發工具CountDownLatch

clas 允許 his wait方法 輸出 throw 引用 excel文件 inter   CountDownLatch允許一個或則多個線程等待其他線程完成操作。   假如我們有這樣的需求:我們需要解析一個excel文件中的多個sheet,我們可以考慮使用多線程,每一個線

Java並發工具並發數控制神器Semaphore

static eight 構造方法 許可證 for pan 應用場景 都是 ole   Semaphore(信號量)使用來控制通知訪問特定資源的線程數量,它通過協調各個線程,以保證合理的使用公共資源。   我們可以這麽理解Semaphore,比如一個廁所只有6個坑,同時只能

Java並發工具線程間數據交換工具Exchanger

catch exchanger 系統 chang data 完成後 () time ktr   Exchanger是一個用於線程間協做的工具類,主要用於線程間的數據交換。它提供了一個同步點,在這個同步點,兩個線程可以彼此交換數據。兩個線程通過exchange方法交換數據,如

【轉】角落的開發工具VsVisual Studio)2017插件推薦

diff image 下載 場景 圖像 部分 bundle emmet down 因為最近錄制視頻的緣故,很多朋友都在QQ群留言,或者微信公眾號私信我,問我一些工具和一些插件啊,怎麽使用的啊?那麽今天我忙裏偷閑整理一下清單,然後在這裏面公布出來。 Visual Stu

多線程——工具Semaphore

nes sha 阻塞 bool eth 創建 執行 pri 工具類 一、Semaphore功能介紹 Semaphore類相當於線程計數器,在獲取Semaphore對象時設定可以產生的線程總數(線程並不是Semaphore類生成的,它只是統計線程的數量),創建Semaphor

並發編程常用工具countDownLatch和cyclicBarrier的使用對比

開放 spa 圖片 我們 啟用 線程 分享 ride 在線 1.CountDownLatch countDownLatch的作用是讓一組線程等待其他線程完成工作以後在執行,相當於加強版的join(不懂可以百度一下join的用法),一般在初始化的時候會在構

前端常用外掛、工具庫彙總

前言 在開發中,我們經常會將一些常用的程式碼塊、功能塊進行封裝,為的是更好的複用。那麼,被抽離出來獨立完成功能,通過API或配置項和其他部分互動,便形成了外掛。 下面這些是我在工作中積累的一些常用的前端開源外掛,這裡只是羅列出來,詳細的用法各個外掛官網或者Gayhub都有介紹。注意:往往一個解決方案會

前端常用外掛、工具庫彙總

前言 對本文感興趣可以先加個收藏,也可以轉發分享給身邊的小夥伴,以後遇到類似的場景就來看看具體的外掛及其用法。 上一篇《前端常用外掛、工具類庫彙總(上)》內容摘要: 動畫庫 滾動庫 輪播圖 滾屏 彈出框 訊息通知 下拉框 級聯選擇器

初夏小談:斐波那契三種實現方法C語言版第三種相信沒見過

斐波那契數列(Fibonaccisequnce),又稱黃金分割數列。研究斐波那契數列有相當重要的價值,例在現代物理、準晶體結構、化學等領域都有直接的應用。因此研究斐波那契數列也是很有必要的。 今天初夏將為大家帶來計算斐波那契數列第n位的三種方法 第一種利用遞迴的方法計算,程式碼相當簡單,但其

netty原始碼閱讀效能優化工具Recycle異執行緒獲取物件

在這篇《netty原始碼閱讀之效能優化工具類之Recycler獲取物件》文章裡面,我們還有一個scavenge()方法沒有解析,也就是在別的執行緒裡面回收物件。下面我們開始介紹,從這個方法開始進入: boolean scavenge() { // con

juc併發工具CountDownLatch閉鎖

import java.util.concurrent.CountDownLatch;/** * 閉鎖: 在進行某些運算時, 只有其他所有執行緒的運算全部完成,當前運算才繼續執行(程式流中加了一道柵欄) * 聯想: 相當於水電站的水壩, 會攔截上游的水, 當積累到一定水位才放水. * 馬場賽馬,需要

System getProperties方法

getProperties()方法:確定當前的系統屬性。 1 package SystemTest; 2 /** 3 獲得當前類的完整路徑。最後一句 4 */ 5 6 7 import java.net.MalformedURLException;

傳送郵件工具及操作例子

1.所需要工具類  1.1ExcelUtil工具     package com.finlabtech.pinjamancepatanalyse.util; import org.apache.poi.hssf.util