Android SpannableString(顯示多樣式文本)

SpannableString與String相似,是一種字符串類型,TextView可以直接設置Spannable為顯示文本,不相同的是,SpannableString可以使用setSpan方法實現字符串各種形式風格的顯示,并且可以設置指定的區間。

setSpan(Object what, int start, int end, int flags)方法需要用戶輸入四個參數,what表示設置的格式是什么,可以是前景色、背景色也可以是可點擊的文本等等(URLSpan、ClickableSpan、BackgroundColorSpan、ForegroundColorSpan、MaskFilterSpan、AbsoluteSizeSpan、RelativeSizeSpan、ImageSpan、ScaleXSpan、StyleSpan、SubscriptSpan、SuperscriptSpan、TextAppearanceSpan、TypefaceSpan、RasterizerSpan、StrikethroughSpan、UnderlineSpan)。MaskFilterSpan可以實現模糊和浮雕效果,RasterizerSpan可以實現光柵效果。start表示需要設置格式的子字符串的起始下標,同理end表示終了下標,flags屬性就有意思了,共有四種屬性:

  • Spanned.SPAN_INCLUSIVE_INCLUSIVE:前后都包括
  • Spanned.SPAN_EXCLUSIVE_EXCLUSIVE:前后都不包括
  • Spanned.SPAN_INCLUSIVE_EXCLUSIVE:前面包括,后面不包括
  • Spanned.SPAN_EXCLUSIVE_INCLUSIVE:前面不包括,后面包括

SpannableStringBuilder實現對SpannableString的一個拼接效果,append()方法可以實現各種風格效果的SpannableString拼接,非常實用。

實例代碼

  1. activity.xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_marginTop="10dp"
    tools:context="com.mazaiting.spannablestring.MainActivity"
    >

  <TextView
      android:id="@+id/textView"
      android:layout_gravity="center"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Hello World!"
      />

  <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:orientation="horizontal"
      >
    <Button
        android:onClick="foreGroundColor"
        android:text="前景色"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        />

    <Button
        android:onClick="backGroundColor"
        android:text="背景色"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        />

    <Button
        android:onClick="relativeSize"
        android:text="字體大小"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        />
    <Button
        android:onClick="strikeThrough"
        android:text="刪除線"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        />
  </LinearLayout>

  <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:orientation="horizontal"
      >
    <Button
        android:onClick="underLine"
        android:text="下劃線"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        />

    <Button
        android:onClick="superScript"
        android:text="上標"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        />

    <Button
        android:onClick="subScript"
        android:text="下標"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        />
    <Button
        android:onClick="styleSpan"
        android:text="粗體斜體"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        />
  </LinearLayout>

  <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:orientation="horizontal"
      >
    <Button
        android:onClick="imageSpan"
        android:text="圖片"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        />

    <Button
        android:onClick="click"
        android:text="點擊"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        />

    <Button
        android:onClick="urlSpan"
        android:text="URL"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        />
    <Button
        android:onClick="styleSpan"
        android:text="粗體斜體"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        />
  </LinearLayout>
</LinearLayout>

  1. MainActivity.java代碼
package com.mazaiting.spannablestring;

import android.content.Intent;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.method.LinkMovementMethod;
import android.text.style.BackgroundColorSpan;
import android.text.style.ClickableSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.ImageSpan;
import android.text.style.RelativeSizeSpan;
import android.text.style.StrikethroughSpan;
import android.text.style.StyleSpan;
import android.text.style.SubscriptSpan;
import android.text.style.SuperscriptSpan;
import android.text.style.URLSpan;
import android.text.style.UnderlineSpan;
import android.util.TypedValue;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
  private TextView textView;
  @Override protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    textView = (TextView) this.findViewById(R.id.textView);

  }

  /**
   * 設置前景色
   */
  public void foreGroundColor(View view){
    SpannableString spannableString = new SpannableString("設置文字的前景色為淡藍色");
    ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(Color.parseColor("#0099EE"));
    spannableString.setSpan(foregroundColorSpan, 9, spannableString.length(),
        Spanned.SPAN_INCLUSIVE_INCLUSIVE);
    textView.setText(spannableString);
  }

  /**
   * 設置背景色
   */
  public void backGroundColor(View view){
    SpannableString spannableString = new SpannableString("設置文字的背景色為淺綠色");
    BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(Color.parseColor("#AC00FF30"));
    spannableString.setSpan(backgroundColorSpan, 9, spannableString.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
    textView.setText(spannableString);
  }

  /**
   * 設置文字大小
   */
  public void relativeSize(View view){
    SpannableString spannableString = new SpannableString("萬丈高樓平地起");
    RelativeSizeSpan relativeSizeSpan1 = new RelativeSizeSpan(1.2f);
    RelativeSizeSpan relativeSizeSpan2 = new RelativeSizeSpan(1.4f);
    RelativeSizeSpan relativeSizeSpan3 = new RelativeSizeSpan(1.6f);
    RelativeSizeSpan relativeSizeSpan4 = new RelativeSizeSpan(1.8f);
    RelativeSizeSpan relativeSizeSpan5 = new RelativeSizeSpan(1.6f);
    RelativeSizeSpan relativeSizeSpan6 = new RelativeSizeSpan(1.4f);
    RelativeSizeSpan relativeSizeSpan7 = new RelativeSizeSpan(1.2f);

    spannableString.setSpan(relativeSizeSpan1, 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    spannableString.setSpan(relativeSizeSpan2, 1, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    spannableString.setSpan(relativeSizeSpan3, 2, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    spannableString.setSpan(relativeSizeSpan4, 3, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    spannableString.setSpan(relativeSizeSpan5, 4, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    spannableString.setSpan(relativeSizeSpan6, 5, 6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    spannableString.setSpan(relativeSizeSpan7, 6, 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

    textView.setText(spannableString);
  }

  /**
   * 設置刪除線
   */
  public void strikeThrough(View view){
    SpannableString spannableString = new SpannableString("為文字設置刪除線");
    StrikethroughSpan strikethroughSpan = new StrikethroughSpan();
    spannableString.setSpan(strikethroughSpan, 5, spannableString.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
    textView.setText(spannableString);
  }

  /**
   * 設置下劃線
   */
  public void underLine(View view){
    SpannableString spannableString = new SpannableString("為文字設置下劃線");
    UnderlineSpan underlineSpan = new UnderlineSpan();
    spannableString.setSpan(underlineSpan, 5, spannableString.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
    textView.setText(spannableString);
  }

  /**
   * 設置上標
   */
  public void superScript(View view){
    SpannableString spannableString = new SpannableString("為文字設置上標");
    SuperscriptSpan superscriptSpan = new SuperscriptSpan();
    spannableString.setSpan(superscriptSpan, 5, spannableString.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
    textView.setText(spannableString);
  }

  /**
   * 設置下標
   */
  public void subScript(View view){
    SpannableString spannableString = new SpannableString("為文字設置下標");
    SubscriptSpan subscriptSpan = new SubscriptSpan();
    spannableString.setSpan(subscriptSpan, 5, spannableString.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
    textView.setText(spannableString);
  }

  /**
   * 設置粗體斜體
   */
  public void styleSpan(View view){
    SpannableString spannableString = new SpannableString("為文字設置粗體、斜體風格");
    StyleSpan styleSpan_B = new StyleSpan(Typeface.BOLD);
    StyleSpan styleSpan_I = new StyleSpan(Typeface.ITALIC);
    spannableString.setSpan(styleSpan_B, 5, 7, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
    spannableString.setSpan(styleSpan_I, 8, 10, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
    textView.setText(spannableString);
  }

  /**
   * 設置圖片
   */
  public void imageSpan(View view){
    SpannableString spannableString = new SpannableString("在文本中添加表情(表情)");
    Drawable drawable = getResources().getDrawable(R.mipmap.emotion);
    drawable.setBounds(0, 0, 42, 42);
    ImageSpan imageSpan = new ImageSpan(drawable);
    spannableString.setSpan(imageSpan, 6, 8, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
    textView.setText(spannableString);
  }

  /**
   * 點擊開啟新界面
   */
  public void click(View view){
    SpannableString spannableString = new SpannableString("為文字設置點擊事件");
    MyClickableSpan clickableSpan = new MyClickableSpan("http://www.lxweimin.com/");
    spannableString.setSpan(clickableSpan, 5, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
    // 使用ClickableSpan的文本如果想真正實現點擊作用,
    // 必須為TextView設置setMovementMethod方法,否則沒有點擊相應,
    // 至于setHighlightColor方法則是控制點擊是的背景色。
    textView.setMovementMethod(LinkMovementMethod.getInstance());
    textView.setHighlightColor(Color.parseColor("#36969696"));
    textView.setText(spannableString);
  }

  class MyClickableSpan extends ClickableSpan {

    private String content;

    public MyClickableSpan(String content) {
      this.content = content;
    }

    @Override public void updateDrawState(TextPaint ds) {
      ds.setUnderlineText(false);
    }

    @Override public void onClick(View widget) {
      Intent intent = new Intent(MainActivity.this, SecondActivity.class);
      Bundle bundle = new Bundle();
      bundle.putString("content", content);
      intent.putExtras(bundle);
      startActivity(intent);
    }
  }

  /**
   * 網絡鏈接
   */
  public void urlSpan(View view) {
    SpannableString spannableString = new SpannableString("為文字設置超鏈接");
    URLSpan urlSpan = new URLSpan("http://www.lxweimin.com/");
    spannableString.setSpan(urlSpan, 5, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
    textView.setMovementMethod(LinkMovementMethod.getInstance());
    textView.setHighlightColor(Color.parseColor("#36969696"));
    textView.setText(spannableString);
  }
}

注: 文章中涉及到的Activity即一個空的Activity, 讀者可以可以新建一個空界面即可。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,182評論 6 543
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,489評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,290評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,776評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,510評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,866評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,860評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,036評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,585評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,331評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,536評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,058評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,754評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,154評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,469評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,273評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,505評論 2 379

推薦閱讀更多精彩內容