Android-自定义TextView(彩色字体与霓虹灯字体以及TextView的多项字体效果)

很多时候我们也需要制作一些彩色字体的文本,文本的霓虹灯效果,以及链接字体哈,字体背景色,下标之类的,而很多时候我们却用多个textview去达到这个效果,可以说是很浪费时间浪费经精力的,这时候怎么办呢?下面就有详解。


文章结构:1.自定义TextView实现彩色字体与霓虹灯字体 2.一个可以字体实现多项效果的类(封装好了,可直接使用)


先上图看看我们要做的效果这里写图片描述

一、自定义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 方法中获取到宽度,并对各个类进行初始化
        if (TextViewWidth == 0) {
            TextViewWidth = getMeasuredWidth();
            if (TextViewWidth > 0) {
                //得到 父类 TextView 中写字的那支笔
                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" />

<!-- 霓虹灯字体,一会就不贴xml了-->
    <com.demo.myview.colourfulFontOrNeonTextView.NenoTextview
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:text="霓虹灯字体!霓虹灯字体!霓虹灯字体!"
        android:textSize="28sp" />
<!-- 多项字体效果,一会就不贴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正常粗体斜体粗斜体上标下标前景色背景色图片"
        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 方法中获取到宽度,并对各个类进行初始化
        if (mViewWidth == 0) {
            mViewWidth = getMeasuredWidth();

            if (mViewWidth > 0) {
                //得到 父类 TextView 中写字的那支笔.,注意是继承Textview
                mPaint = getPaint();
                //初始化线性渲染器 不了解的请看上面连接
                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的原意是对一个Bitmap的图片变化进行处理,它本身不能对图像或者View进行变换,但是可以与其他的API结合进行图形和View的变换,比如Canvas
                mMatrix = new Matrix();

            }
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //先让父类方法执行,由于上面我们给父类的 Paint 套上了渲染器,所以这里出现的文字已经是彩色的了
        super.onDraw(canvas);

        if (mMatrix != null) {
            //利用 Matrix 的平移动作实现霓虹灯的效果,这里是每次滚动1/10
            mTranslate += mViewWidth / 10;
            //如果滚出了控件边界,就要拉回来重置开头,这里重置到了屏幕左边的空间
            if (mTranslate >  mViewWidth) {
                mTranslate = -mViewWidth/2;
            }
            //设置平移距离
            mMatrix.setTranslate(mTranslate, 0);
            //平移效果生效
            mLinearGradient.setLocalMatrix(mMatrix);
            //延迟 100 毫秒再次刷新 View 也就是再次执行本 onDraw 方法
            postInvalidateDelayed(50);

        }
    }
}

xml中的引用已经在上面给出了。


三、多项字体效果,下面将给出一个封装好的类以及调用方法

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:标识在 Span 范围内的文本前后输入新的字符时是否把它们也应用这个效果
        //  Spanned.SPAN_EXCLUSIVE_EXCLUSIVE(前后都不包括)、
        //  Spanned.SPAN_INCLUSIVE_EXCLUSIVE(前面包括,后面不包括)、
        // Spanned.SPAN_EXCLUSIVE_INCLUSIVE(前面不包括,后面包括)、
        // Spanned.SPAN_INCLUSIVE_INCLUSIVE(前后都包括)
        //设置字体(default,default-bold,monospace,serif,sans-serif)
        ss.setSpan(new TypefaceSpan("monospace"), 6, 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        // 设置网络超链接
        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);
        // 设置字体颜色
        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);
        // 设置字体大小
        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);
        // 设置下划线
        ss.setSpan(new MyUnderlineSpan(), content.indexOf("youku"), content.indexOf("正常"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        //设置字体样式正常,粗体,斜体,粗斜体
        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("上标"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);  //粗斜体

        //设置上下标
        ss.setSpan(new SubscriptSpan(), content.indexOf("上标"), content.indexOf("下标"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);     //下标
        ss.setSpan(new SuperscriptSpan(), content.indexOf("下标"), content.indexOf("前景色"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);   //上标

        //设置字体前景色
        ss.setSpan(new ForegroundColorSpan(Color.MAGENTA), content.indexOf("前景色"), content.indexOf("背景色"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);  //设置前景色为洋红色

        //设置字体背景色
        ss.setSpan(new BackgroundColorSpan(Color.CYAN), content.indexOf("背景色"), content.indexOf("图片"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);  //设置背景色为青色
//设置图片
        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;
    }

    //这里是干嘛的呢?为了设置下划线呗
    static class MyUnderlineSpan extends UnderlineSpan {

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

    //这又是干嘛的呢?计算字体大小嘛
    private static int sp2px(Context context, float spValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (spValue * fontScale + 0.5f);
    }
}

嗯,,还缺个调用,为了方便新手使用,下面也贴出来:

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的多项字体效果都写清楚了,欢迎大家在下方指出错误,共同学习!

转载请注明:【JackFrost的博客】

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值