Android中Textview文字設置不同顏色、下劃線、加粗、超鏈接

在項目中會遇到在一行文字,部分需要不同的文字顏色、下劃線以及超鏈接來展示,下面介紹兩種方式實現:

1、SpannableString來實現

1)簡介

對於給Textview設置不同顏色,就不得不提SpannableString,當然給textview設置不同的字體顏色也可以通過加HTML標籤來實現,但是有SpannableString的存在,爲啥不用呢.(相比Html 相對簡短易理解但還是建議掌握SpannableString)。

先簡單的介紹一下SpannableString,SpannableStringBuilder.

首先SpannableString、SpannableStringBuilder基本上與String差不多,也是用來存儲字符串,但它們倆的特殊就在於有一個SetSpan()函數,

能給這些存儲的String添加各種格式或者稱樣式(Span),將原來的String以不同的樣式顯示出來,比如在原來String上加下劃線、加背景色、改變字體

顏色、用圖片把指定的文字給替換掉,加超鏈接等等。總而言之,SpannableString和SpannableStringBuilder和string差不多,但是不能給字符串設置

不同的樣式.

注意:如果這些額外信息能被所用的方式支持,比如將SpannableString傳給TextView;也有對這些額外信息不支持的,比如自定義view中Canvas繪製

文字,對於不支持的情況,SpannableString和SpannableStringBuilder就是退化爲String類型,直接顯示原來的String字符串,而不會再顯示這些附加的

額外信息。

當然,SpannableString和SpannableStringBuilder也是存在區別的,它們的區別在於 SpannableString像一個String一樣,構造對象的時候傳入一個

String,之後再無法更改String的內容,也無法拼接多個 SpannableString;而SpannableStringBuilder則更像是StringBuilder,它可以通過其append()方

法來拼接多個String.

//使用SpannableString,必須一次傳入,構造完成 
//使用SpannableStringBuilder,可以使用append()再添加 

SpannableStringBuilder bWord = newSpannableStringBuilder();
bWord.append("我愛大前端");
bWord.append("和全棧");

由於SpannableString和SpannableStringBuilder都實現了CharSequence接口,所以可以直接把SpannableString和SpannableStringBuilder通過TextView.setText()設置給TextView。

2)具體使用

給文本設置不同的樣式是通過setSpan()方法來實現的,其中的具體樣式根據參數來定義。

主要實現方法 SpannableString.setSpan(Object what, int start, int end, int flags)

what 參數,控制文本效果,主要有以下類型
BackgroundColorSpan 背景色
ClickableSpan 點擊事件
ForegroundColorSpan 文本顏色(前景色)
MaskFilterSpan 修飾效果,如模糊(BlurMaskFilter)浮雕(EmbossMaskFilter)
MetricAffectingSpan 父類,一般不用
RasterizerSpan 光柵效果
StrikethroughSpan 刪除線
SuggestionSpan 佔位符
UnderlineSpan 下劃線
AbsoluteSizeSpan 文本字體,絕對大小
DynamicDrawableSpan 設置圖片,基於文本基線或底部對齊
ImageSpan 圖片
RelativeSizeSpan 文本字體,相對大小
ReplacementSpan 父類,一般不用
ScaleXSpan 基於x軸縮放
StyleSpan 字體樣式:粗體、斜體等
SubscriptSpan 下標(數學公式會用到)
SuperscriptSpan 上標(數學公式會用到)
TextAppearanceSpan 文本外貌(包括字體、大小、樣式和顏色)
TypefaceSpan 文本字體
URLSpan 文本超鏈接
start、end 參數
start 指定span開始位置。包括該位置。 
end 指定span結束位置,不包括該位置。

flags 參數,指定前後文本會不會用span樣式
Spannable.SPAN_INCLUSIVE_EXCLUSIVE 前面用,後面不用
Spannable.SPAN_INCLUSIVE_INCLUSIVE 前後都會使用span樣式
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE 前後都不會使用span樣式
Spannable.SPAN_EXCLUSIVE_INCLUSIVE 前面不用,後面用

具體的介紹就是上面,就不一一舉例子

package com.xaaccp.myapp;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.res.ColorStateList;
import android.content.res.XmlResourceParser;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.BackgroundColorSpan;
import android.text.style.BulletSpan;
import android.text.style.ForegroundColorSpan;
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.TextAppearanceSpan;
import android.text.style.TypefaceSpan;
import android.text.style.URLSpan;
import android.text.style.UnderlineSpan;
import android.widget.TextView;

import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;

public class MainActivity extends Activity {

    TextView mTextView = null;
    SpannableString msp = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTextView = (TextView) findViewById(R.id.tv);

        //創建一個 SpannableString對象
        msp = new SpannableString("字體測試字體大小一半兩倍前景色背景色正常粗體斜體粗斜體下劃線刪除線x8x3電話郵件網站短信彩信地圖X軸綜合/bot");

        //設置字體(default,default-bold,monospace,serif,sans-serif)
        msp.setSpan(new TypefaceSpan("monospace"), 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        msp.setSpan(new TypefaceSpan("serif"), 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        //設置字體大小(絕對值,單位:像素)
        msp.setSpan(new AbsoluteSizeSpan(20), 4, 6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        msp.setSpan(new AbsoluteSizeSpan(20, true), 6, 8, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //第二個參數boolean dip,如果爲true,表示前面的字體大小單位爲dip,否則爲像素,同上。

        //設置字體大小(相對值,單位:像素) 參數表示爲默認字體大小的多少倍
        msp.setSpan(new RelativeSizeSpan(0.5f), 8, 10, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //0.5f表示默認字體大小的一半
        msp.setSpan(new RelativeSizeSpan(2.0f), 10, 12, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //2.0f表示默認字體大小的兩倍

        //設置字體前景色
        msp.setSpan(new ForegroundColorSpan(Color.MAGENTA), 12, 15, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //設置前景色爲洋紅色

        //設置字體背景色
        msp.setSpan(new BackgroundColorSpan(Color.CYAN), 15, 18, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //設置背景色爲青色

        //設置字體樣式正常,粗體,斜體,粗斜體
        msp.setSpan(new StyleSpan(Typeface.NORMAL), 18, 20, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //正常
        msp.setSpan(new StyleSpan(Typeface.BOLD), 20, 22, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //粗體
        msp.setSpan(new StyleSpan(Typeface.ITALIC), 22, 24, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //斜體
        msp.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 24, 27, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //粗斜體

        //設置下劃線
        msp.setSpan(new UnderlineSpan(), 27, 30, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        //設置刪除線
        msp.setSpan(new StrikethroughSpan(), 30, 33, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        //設置上下標
        msp.setSpan(new SubscriptSpan(), 34, 35, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //下標
        msp.setSpan(new SuperscriptSpan(), 36, 37, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //上標

        //超級鏈接(需要添加setMovementMethod方法附加響應)
        msp.setSpan(new URLSpan("tel:10086"), 37, 39, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //電話
        msp.setSpan(new URLSpan("[email protected]"), 39, 41, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //郵件
        msp.setSpan(new URLSpan("http://www.baidu.com "), 41, 43, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //網絡
        msp.setSpan(new URLSpan("sms:10086"), 43, 45, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //短信 使用sms:或者smsto:
        msp.setSpan(new URLSpan("mms:10086"), 45, 47, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //彩信 使用mms:或者mmsto:
        msp.setSpan(new URLSpan("geo:38.899533,-77.036476"), 47, 49, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //地圖
        //設置字體大小(相對值,單位:像素) 參數表示爲默認字體寬度的多少倍
        msp.setSpan(new ScaleXSpan(2.0f), 49, 51, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //2.0f表示默認字體寬度的兩倍,即X軸方向放大爲默認字體的兩倍,而高度不變
        //設置字體(依次包括字體名稱,字體大小,字體樣式,字體顏色,鏈接顏色)
        ColorStateList csllink = null;
        ColorStateList csl = null;

//        @SuppressLint("ResourceType") XmlResourceParser xppcolor = getResources().getXml(R.color.color);
//        try {
//            csl = ColorStateList.createFromXml(getResources(), xppcolor);
//        } catch (XmlPullParserException e) {
//            e.printStackTrace();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }

//        @SuppressLint("ResourceType") XmlResourceParser xpplinkcolor = getResources().getXml(R.color.linkcolor);
//        try {
//            csllink = ColorStateList.createFromXml(getResources(), xpplinkcolor);
//        } catch (XmlPullParserException e) {
//            e.printStackTrace();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }

        msp.setSpan(new TextAppearanceSpan("monospace",android.graphics.Typeface.BOLD_ITALIC, 30, csl, csllink), 51,
                53, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        //設置項目符號
        msp.setSpan(new BulletSpan(android.text.style.BulletSpan.STANDARD_GAP_WIDTH,Color.GREEN),0 ,msp.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        //<span style="font-family: Arial;"> //第一個參數表示項目符號佔用的寬度,第二個參數爲項目符號的顏色 </span>


        //設置圖片
        // Drawable drawable = getResources().getDrawable(R.drawable.ic_launcher);
        // drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
        // msp.setSpan(new ImageSpan(drawable), 53, 57, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        mTextView.setText(msp);
        mTextView.setMovementMethod(LinkMovementMethod.getInstance());

    }
}

2、用HTML的方式實現:

結構如下

java.lang.Object

   ↳

android.text.Html

類用於處理的HTML字符串並將其轉換成可顯示的樣式文本。但並不是所有的HTML標記的支持。

說其簡單是應爲它就有四個方法:

                              Public Methods

static String

escapeHtml(CharSequence text)

從給定的代表性名文中返回Html轉義字符。

static Spanned

fromHtml(String source)

從Html字符串中返回可顯示的樣式文本。

static Spanned

fromHtml(String source, Html.ImageGetter imageGetter, Html.TagHandler tagHandler)

從Html字符串中返回可顯示的樣式文本

static String

toHtml(Spanned text)

將文本轉換成Html。

設置不用顏色如下

TextView mTextView=(TextView)findViewById(R.id.tv); 

String str="<font color='#4d8ade'>只會玩戰士</font>回覆<font color='#4d8ade'>冷雲他大叔</font>:啊哈哈哈或"; 

mTextView.setTextSize(15); 

mTextView.setText(Html.fromHtml(str));

設置下劃線如下

mTextView.setText(Html.fromHtml("已有賬號,去"+"<u>"+"登陸"+"</u>"));

 

PS:如果不在HTML標籤最前面加入其他HTML元素,此函數可能不會生效。

 

 

 

書到用時方恨少,紙上得來終覺淺。希望對你有所幫助!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章