Android-自定義TextView(彩色字體與霓虹燈字體以及TextView的多項(xiàng)字體效果)

很多時(shí)候我們也需要制作一些彩色字體的文本英上,文本的霓虹燈效果胧瓜,以及鏈接字體哈,字體背景色跺株,下標(biāo)之類(lèi)的复濒,而很多時(shí)候我們卻用多個(gè)textview去達(dá)到這個(gè)效果脖卖,可以說(shuō)是很浪費(fèi)時(shí)間浪費(fèi)經(jīng)精力的,這時(shí)候怎么辦呢巧颈?下面就有詳解胚嘲。


文章結(jié)構(gòu):1.自定義TextView實(shí)現(xiàn)彩色字體與霓虹燈字體 2.一個(gè)可以字體實(shí)現(xiàn)多項(xiàng)效果的類(lèi)(封裝好了,可直接使用)


先上圖看看我們要做的效果
這里寫(xiě)圖片描述

一洛二、自定義TextView之彩色字體,直接上代碼解釋

package com.demo.myview.colourfulFontOrNeonTextView;

import android.content.Context;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.widget.TextView;

/**
 * Created by 符柱成 on 2016/8/19.
 */
public class ColourfulFontTextview extends TextView {

    int TextViewWidth;                      //TextView的寬度
    private LinearGradient mLinearGradient;     //渲染器
    private Paint paint;


    public ColourfulFontTextview(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        //在 onSizeChanged 方法中獲取到寬度馋劈,并對(duì)各個(gè)類(lèi)進(jìn)行初始化
        if (TextViewWidth == 0) {
            TextViewWidth = getMeasuredWidth();
            if (TextViewWidth > 0) {
                //得到 父類(lèi) TextView 中寫(xiě)字的那支筆
                paint = getPaint();
                //初始化線性渲染器
                mLinearGradient = new LinearGradient(0, 0, TextViewWidth, 0,
                        new int[]{Color.BLUE, Color.YELLOW, Color.RED, Color.GREEN, Color.GRAY}, null, Shader.TileMode.CLAMP);
                //把渲染器給筆套上
                paint.setShader(mLinearGradient);

            }
        }
    }
}

2.在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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    android:orientation="vertical"
    tools:context=".colourfulFontOrNeonTextView.ColourfulFontOrNeonAcitivity">

    <com.demo.myview.colourfulFontOrNeonTextView.colourfulFontTextview
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="彩色字體!彩色字體!彩色字體!"
        android:textSize="28sp" />

<!-- 霓虹燈字體,一會(huì)就不貼xml了-->
    <com.demo.myview.colourfulFontOrNeonTextView.NenoTextview
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:text="霓虹燈字體晾嘶!霓虹燈字體妓雾!霓虹燈字體!"
        android:textSize="28sp" />
<!-- 多項(xiàng)字體效果垒迂,一會(huì)就不貼xml了-->

    <TextView
        android:id="@+id/tv_content"
        android:layout_width="match_parent"
        android:layout_height="130dp"
        android:layout_marginTop="10dp"
        android:background="@color/colorPrimary"
        android:text="baiduoryouku正常粗體斜體粗斜體上標(biāo)下標(biāo)前景色背景色圖片"
        android:textSize="25sp"/>

</LinearLayout>

二械姻、自定義TextView之霓虹燈字體,直接上代碼解釋啦

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.widget.TextView;

/**
 * Created by 符柱成 on 2016/8/19.
 */
public class NenoTextview extends TextView {
    int mViewWidth;                          //TextView的寬度
    private LinearGradient mLinearGradient;     //渲染器
    private Matrix mMatrix;         //圖片變換處理器
    private Paint mPaint;           //字體的筆
    int mTranslate=0;       //表示平移的速度

    public NenoTextview(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        //在 onSizeChanged 方法中獲取到寬度机断,并對(duì)各個(gè)類(lèi)進(jìn)行初始化
        if (mViewWidth == 0) {
            mViewWidth = getMeasuredWidth();

            if (mViewWidth > 0) {
                //得到 父類(lèi) TextView 中寫(xiě)字的那支筆.楷拳,注意是繼承Textview
                mPaint = getPaint();
                //初始化線性渲染器 不了解的請(qǐng)看上面連接
                mLinearGradient = new LinearGradient(0, 0, mViewWidth, 0,
                        new int[]{Color.BLUE, Color.YELLOW, Color.RED, Color.GREEN}, null, Shader.TileMode.CLAMP);
                //把渲染器給筆套上
                mPaint.setShader(mLinearGradient);
                //初始化 Matrix,Matrix的原意是對(duì)一個(gè)Bitmap的圖片變化進(jìn)行處理吏奸,它本身不能對(duì)圖像或者View進(jìn)行變換欢揖,但是可以與其他的API結(jié)合進(jìn)行圖形和View的變換,比如Canvas
                mMatrix = new Matrix();

            }
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //先讓父類(lèi)方法執(zhí)行奋蔚,由于上面我們給父類(lèi)的 Paint 套上了渲染器她混,所以這里出現(xiàn)的文字已經(jīng)是彩色的了
        super.onDraw(canvas);

        if (mMatrix != null) {
            //利用 Matrix 的平移動(dòng)作實(shí)現(xiàn)霓虹燈的效果,這里是每次滾動(dòng)1/10
            mTranslate += mViewWidth / 10;
            //如果滾出了控件邊界泊碑,就要拉回來(lái)重置開(kāi)頭坤按,這里重置到了屏幕左邊的空間
            if (mTranslate >  mViewWidth) {
                mTranslate = -mViewWidth/2;
            }
            //設(shè)置平移距離
            mMatrix.setTranslate(mTranslate, 0);
            //平移效果生效
            mLinearGradient.setLocalMatrix(mMatrix);
            //延遲 100 毫秒再次刷新 View 也就是再次執(zhí)行本 onDraw 方法
            postInvalidateDelayed(50);

        }
    }
}

xml中的引用已經(jīng)在上面給出了。


三馒过、多項(xiàng)字體效果臭脓,下面將給出一個(gè)封裝好的類(lèi)以及調(diào)用方法

package com.demo.myview.colourfulFontOrNeonTextView;

import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.BackgroundColorSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.ImageSpan;
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 com.demo.myview.R;

/**
 * Created by 符柱成 on 2016/8/19.
 */

//封裝好了Textview多種字體
public class SpannableStringFont {
    public static SpannableString changeFont(Context context, String content) {
        SpannableString ss = new SpannableString(content);
        // flag:標(biāo)識(shí)在 Span 范圍內(nèi)的文本前后輸入新的字符時(shí)是否把它們也應(yīng)用這個(gè)效果
        //  Spanned.SPAN_EXCLUSIVE_EXCLUSIVE(前后都不包括)、
        //  Spanned.SPAN_INCLUSIVE_EXCLUSIVE(前面包括腹忽,后面不包括)来累、
        // Spanned.SPAN_EXCLUSIVE_INCLUSIVE(前面不包括,后面包括)留凭、
        // Spanned.SPAN_INCLUSIVE_INCLUSIVE(前后都包括)
        //設(shè)置字體(default,default-bold,monospace,serif,sans-serif)
        ss.setSpan(new TypefaceSpan("monospace"), 6, 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        // 設(shè)置網(wǎng)絡(luò)超鏈接
        ss.setSpan(new URLSpan("http://www.baidu.com"), content.indexOf("baidu"), content.indexOf("or"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        ss.setSpan(new URLSpan("http://www.youku.com"), content.indexOf("youku"), content.indexOf("正常"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        // 設(shè)置字體顏色
        ss.setSpan(new ForegroundColorSpan(Color.parseColor("#ff0000")), content.indexOf("baidu"), content.indexOf("or"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        ss.setSpan(new ForegroundColorSpan(Color.parseColor("#0000FF")), content.indexOf("or"), content.indexOf("youku"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        ss.setSpan(new ForegroundColorSpan(Color.parseColor("#ff00ff")), content.indexOf("youku"), content.indexOf("正常"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        // 設(shè)置字體大小
        ss.setSpan(new AbsoluteSizeSpan(sp2px(context, 25)), content.indexOf("baidu"), content.indexOf("or"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        ss.setSpan(new AbsoluteSizeSpan(sp2px(context, 30)), content.indexOf("youku"), content.indexOf("正常"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        // 設(shè)置下劃線
        ss.setSpan(new MyUnderlineSpan(), content.indexOf("youku"), content.indexOf("正常"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        //設(shè)置字體樣式正常佃扼,粗體偎巢,斜體蔼夜,粗斜體
        ss.setSpan(new StyleSpan(android.graphics.Typeface.NORMAL), content.indexOf("正常"), content.indexOf("粗體"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);  //正常
        ss.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), content.indexOf("粗體"), content.indexOf("斜體"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);  //粗體
        ss.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), content.indexOf("斜體"), content.indexOf("粗斜體"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);  //斜體
        ss.setSpan(new StyleSpan(android.graphics.Typeface.BOLD_ITALIC), content.indexOf("粗斜體"), content.indexOf("上標(biāo)"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);  //粗斜體

        //設(shè)置上下標(biāo)
        ss.setSpan(new SubscriptSpan(), content.indexOf("上標(biāo)"), content.indexOf("下標(biāo)"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);     //下標(biāo)
        ss.setSpan(new SuperscriptSpan(), content.indexOf("下標(biāo)"), content.indexOf("前景色"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);   //上標(biāo)

        //設(shè)置字體前景色
        ss.setSpan(new ForegroundColorSpan(Color.MAGENTA), content.indexOf("前景色"), content.indexOf("背景色"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);  //設(shè)置前景色為洋紅色

        //設(shè)置字體背景色
        ss.setSpan(new BackgroundColorSpan(Color.CYAN), content.indexOf("背景色"), content.indexOf("圖片"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);  //設(shè)置背景色為青色
//設(shè)置圖片
        Drawable drawable = context.getDrawable(R.drawable.home_serve_dot_pressed);
        drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
        ss.setSpan(new ImageSpan(drawable), content.indexOf("圖片"), ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        return ss;
    }

    //這里是干嘛的呢?為了設(shè)置下劃線唄
    static class MyUnderlineSpan extends UnderlineSpan {

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

    //這又是干嘛的呢压昼?計(jì)算字體大小嘛
    private static int sp2px(Context context, float spValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (spValue * fontScale + 0.5f);
    }
}


嗯求冷,瘤运,還缺個(gè)調(diào)用,為了方便新手使用匠题,下面也貼出來(lái):

public class ColourfulFontOrNeonAcitivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_colourful_font_or_neon_acitivity);
        initView();
    }
    private void initView(){
        TextView textView = (TextView) findViewById(R.id.tv_content);
        String content = textView.getText().toString();
        textView.setText(SpannableStringFont.changeFont(ColourfulFontOrNeonAcitivity.this,content));
        textView.setMovementMethod(LinkMovementMethod.getInstance());

    }
}

好了拯坟,彩色字體與霓虹燈字體以及TextView的多項(xiàng)字體效果都寫(xiě)清楚了,歡迎大家在下方指出錯(cuò)誤韭山,共同學(xué)習(xí)郁季!

轉(zhuǎn)載請(qǐng)注明:【JackFrost的博客】

更多精彩的內(nèi)容,可以訪問(wèn)JackFrost的博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末钱磅,一起剝皮案震驚了整個(gè)濱河市梦裂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌盖淡,老刑警劉巖年柠,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異褪迟,居然都是意外死亡冗恨,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)味赃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)掀抹,“玉大人,你說(shuō)我怎么就攤上這事心俗】释瑁” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵另凌,是天一觀的道長(zhǎng)谱轨。 經(jīng)常有香客問(wèn)我,道長(zhǎng)吠谢,這世上最難降的妖魔是什么土童? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮工坊,結(jié)果婚禮上献汗,老公的妹妹穿的比我還像新娘。我一直安慰自己王污,他們只是感情好罢吃,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著昭齐,像睡著了一般尿招。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,754評(píng)論 1 307
  • 那天就谜,我揣著相機(jī)與錄音怪蔑,去河邊找鬼。 笑死丧荐,一個(gè)胖子當(dāng)著我的面吹牛缆瓣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播虹统,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼弓坞,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了车荔?” 一聲冷哼從身側(cè)響起昼丑,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎夸赫,沒(méi)想到半個(gè)月后菩帝,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡茬腿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年呼奢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片切平。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡握础,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出悴品,到底是詐尸還是另有隱情禀综,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布苔严,位于F島的核電站定枷,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏届氢。R本人自食惡果不足惜欠窒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望退子。 院中可真熱鬧岖妄,春花似錦、人聲如沸寂祥。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)丸凭。三九已至福扬,卻和暖如春腕铸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背忧换。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工恬惯, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留向拆,地道東北人亚茬。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像浓恳,于是被迫代替她去往敵國(guó)和親刹缝。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,185評(píng)論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)颈将、插件梢夯、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,107評(píng)論 4 62
  • 要求: 完成注冊(cè)界面 完成注冊(cè)模塊的功能(將數(shù)據(jù)成功的插入數(shù)據(jù)庫(kù)中) 進(jìn)行數(shù)據(jù)驗(yàn)證(包括數(shù)據(jù)的完整性,密碼是否一致...
    LYF閑閑閑閑閱讀 322評(píng)論 1 1
  • 我向往那風(fēng)晴圾, 當(dāng)風(fēng)撫動(dòng)你耳旁的亂發(fā), 你會(huì)閉上眼睛享受死姚, 而不會(huì)像一只受驚的小兔一樣逃開(kāi)人乓, 讓我能親吻你的臉龐, ...
    Ice的夢(mèng)閱讀 237評(píng)論 0 0
  • 特別懷念小時(shí)候,媽媽蒸的花卷腌且,糖包榆芦。父母年紀(jì)大了驻右,這些事兒不能勞煩她們了。自己動(dòng)手森爽,豐衣足食爬迟。好吧~_~廢話少說(shuō),...
    尋蕓閱讀 787評(píng)論 11 19