Android開發 SpannableString開發詳解


前言

  SpannableString,是google提供用來處理富文本的功能類.支持很多文本內容的效果變化.另外,它也是Android實現富文本編輯器的關鍵.

關鍵API詳解

     String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。";
        SpannableString spannableString = new SpannableString(content);
        spannableString.setSpan(new ForegroundColorSpan(Color.parseColor("#FFFF0C00"))
                , content.indexOf("創業")
                , content.indexOf("而中")
                , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        mTextView.setText(spannableString);

 

這是一個簡單使用的demo,我們用這個demo來講解一些關鍵點.

這行代碼的關鍵是setSpan(Object what, int start, int end, int flags)方法,這個方法在后面的文字處理將會一直使用到. setSpan有四個參數我們一個一個來講解:

第一個參數 Object what 這個參數主要是提供你需要改變字符串的效果實現類,后續會一一講解並且給出效果圖

第二個參數 int start 這個參數是需要改變的字符串的起始位置

第三個參數 int end 這個參數是需要改變的字符串的結束位置

第四個參數 int flags 是一些字符串新增效果的影響范圍,您可以參考這篇博客https://www.jianshu.com/p/1956e15c9a27這位大神講解的十分詳細了.本着就算是看懂了也要敲一敲代碼記錄的想法,下面也會說明一下常用的4種方法

public static final int SPAN_INCLUSIVE_EXCLUSIVE = SPAN_MARK_MARK; 

在前面/范圍內增加字符,新增字符會跟隨效果.

在后面增加字符,新增字符不會跟隨效果

效果圖:

 

public static final int SPAN_INCLUSIVE_INCLUSIVE = SPAN_MARK_POINT;

在前面/范圍內/后面增加字符,新增字符會跟隨效果.

效果圖:

public static final int SPAN_EXCLUSIVE_EXCLUSIVE = SPAN_POINT_MARK;

在范圍內增加字符,新增字符會跟隨效果.

在前面/后面增加字符,新增字符不會跟隨效果

效果圖:

public static final int SPAN_EXCLUSIVE_INCLUSIVE = SPAN_POINT_POINT;

在范圍內/后面增加字符,新增字符會跟隨效果.

在前面增加字符,新增字符不會跟隨效果.

效果圖:

 

代碼里還有一些其他的常量,但是測試后其他都是這四種基本里一樣的效果.也實在是沒看懂google的注釋.....

文字顏色

以下代碼將一段文字變成紅色

        String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。";
        SpannableString spannableString = new SpannableString(content);
        spannableString.setSpan(new ForegroundColorSpan(Color.parseColor("#FFFF0C00"))
                , content.indexOf("創業")
                , content.indexOf("而中")
                , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        mTextView.setText(spannableString);    

 

ForegroundColorSpan 注意這個類是關鍵,他實現文字顏色改變.

效果圖:

文字背景顏色

        String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。";
        SpannableString spannableString = new SpannableString(content);
        spannableString.setSpan(new BackgroundColorSpan(Color.parseColor("#FFFF0C00"))
                , content.indexOf("創業")
                , content.indexOf("而中")
                , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        mTextView.setText(spannableString);

 

BackgroundColorSpan 注意這個類是關鍵,他實現文字背景顏色改變.

效果圖:

字體

 

        String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。";
        SpannableString spannableString = new SpannableString(content);
        spannableString.setSpan(new TypefaceSpan("sans-serif") //new TypefaceSpan(Typeface.SANS_SERIF) 或者使用這個方法
                , content.indexOf("創業")
                , content.indexOf("而中")
                , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        mTextView.setText(spannableString);

 

效果圖(系統自帶的演示字體效果不明顯):

 

字體大小

        String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。";
        SpannableString spannableString = new SpannableString(content);
        spannableString.setSpan(new AbsoluteSizeSpan(50)
                , content.indexOf("創業")
                , content.indexOf("而中")
                , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        mTextView.setText(spannableString);    

 

效果圖:

 

粗體

        String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。";
        SpannableString spannableString = new SpannableString(content);
        spannableString.setSpan(new StyleSpan(Typeface.BOLD)
                , content.indexOf("創業")
                , content.indexOf("而中")
                , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        mTextView.setText(spannableString);

效果圖:

斜體

        String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。";
        SpannableString spannableString = new SpannableString(content);
        spannableString.setSpan(new StyleSpan(Typeface.ITALIC)
                , content.indexOf("創業")
                , content.indexOf("而中")
                , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        mTextView.setText(spannableString);

 

效果圖:

粗體和斜體

        String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。";
        SpannableString spannableString = new SpannableString(content);
        spannableString.setSpan(new StyleSpan(Typeface.BOLD_ITALIC)
                , content.indexOf("創業")
                , content.indexOf("而中")
                , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        mTextView.setText(spannableString);

 

另外還有一個Typeface.NORMAL  正常值就不演示了

效果圖:

 

刪除線

        String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。";
        SpannableString spannableString = new SpannableString(content);
        spannableString.setSpan(new StrikethroughSpan()
                , content.indexOf("創業")
                , content.indexOf("而中")
                , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        mTextView.setText(spannableString);

 

效果圖:

 

 

下划線

        String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。";
        SpannableString spannableString = new SpannableString(content);
        spannableString.setSpan(new UnderlineSpan()
                , content.indexOf("創業")
                , content.indexOf("而中")
                , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        mTextView.setText(spannableString);

效果圖:

上標

        String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。";
        SpannableString spannableString = new SpannableString(content);
        spannableString.setSpan(new SuperscriptSpan()
                , content.indexOf("創業")
                , content.indexOf("而中")
                , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        mTextView.setText(spannableString);

效果圖:

下標

        String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。";
        SpannableString spannableString = new SpannableString(content);
        spannableString.setSpan(new SubscriptSpan()
                , content.indexOf("創業")
                , content.indexOf("而中")
                , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        mTextView.setText(spannableString);

效果圖:

插入圖片

        String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。";
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
        ImageSpan span = new ImageSpan(bitmap);
        SpannableString spannableString = new SpannableString(content);
        spannableString.setSpan(span
                , 0
                , 1
                , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        mTextView.setText(spannableString);

或者

        String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。";
        Drawable drawable = getResources().getDrawable(R.mipmap.ic_launcher, null); //讀取圖片
        drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());//設置邊界 圖片顯示范圍
        ImageSpan span = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE);//ImageSpan.ALIGN_BASELINE 是對齊方式,這個是基線對齊
        SpannableString spannableString = new SpannableString(content);
        spannableString.setSpan(span
                , 0
                , 1
                , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        mTextView.setText(spannableString);

效果圖:

點擊事件

        mTextView.setMovementMethod(LinkMovementMethod.getInstance());//這是關鍵,只有TextView添加這個后才能有點擊事件
        mTextView.setHighlightColor(getResources().getColor(R.color.fontRed, null));//修改點擊后的背景色
        String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。";
        ClickableSpan clickableSpan = new ClickableSpan() {
            @Override
            public void onClick(@NonNull View widget) {
                Toast.makeText(MainActivity.this, "你點擊了創業未半", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void updateDrawState(@NonNull TextPaint ds) {
                //改變選中文字的顏色或者樣式,注意這里的TextPaint 其實是Paint,可以參考Paint的繪制添加其他效果.
                ds.setColor(Color.RED);
//                super.updateDrawState(ds);
            }
        };
        SpannableString spannableString = new SpannableString(content);
        spannableString.setSpan(clickableSpan
                , content.indexOf("創業")
                , content.indexOf("而中")
                , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        mTextView.setText(spannableString);

setMovementMethod是重中之重,只有設置了才能有 點擊功能

效果圖:

超鏈接

 電話

        mTextView.setMovementMethod(LinkMovementMethod.getInstance());//這是關鍵,只有TextView添加這個后才能有點擊事件
        mTextView.setHighlightColor(getResources().getColor(R.color.fontRed, null));//修改點擊后的背景色
        String content ="先帝創業未半而中道崩殂,今天下三分,益州疲弊,此誠危急存亡之秋也。";
        SpannableString spannableString = new SpannableString(content);
        spannableString.setSpan(new URLSpan("tel:10086")
                , content.indexOf("創業")
                , content.indexOf("而中")
                , Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        mTextView.setText(spannableString);

注意!使用超鏈接,依然要設置setMovementMethod,另外URLSpan也是可以重寫點擊事件的.

 效果圖:

 

與使用Intent的超鏈接類似,也是支持幾個通用的超鏈接,都需要你輸入正確的前綴

  • mailto:123456@qq.com
  • http://www.baidu.com
  • sms:123456
  • mms:123456
  • geo: 38.899533,-77.036476

 

其他Span

  上面的span只是一些常用的span演示,但是其實還有更多的span可以選擇和使用,他們都在這個目錄中.在這個目錄下還有以下這些span.如果后續有時間我會一一實驗使用這些span以判斷他們的功能.

放棄富文本效果,提取文本

之前有端時間苦惱怎么提取不帶富文本格式的文本,因為源代碼的有很多方法並沒有注釋,所以蛋疼了很久..,后面突然發現,直接使用toString()方法就行

spannableString.toString()

 

END


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM