c语言字体颜色上下渐变,Android 自定义TextView实现文字渐变动画

先来看效果

4fb72912282ebd78b3cf0a59bcfcecf3.gif

c88644e446c94871252833b12ffe3715.gif

第一种效果的代码如下,主要是结合Shader实现的

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.LinearGradient;

import android.graphics.Matrix;

import android.graphics.Paint;

import android.graphics.Shader;

import android.util.AttributeSet;

import android.util.Log;

import android.widget.TextView;

public class GradientShaderTextView extends TextView {

private LinearGradient mLinearGradient;

private Matrix mGradientMatrix;

private Paint mPaint;

private int mViewWidth = 0;

private int mTranslate = 0;

private boolean mAnimating = true;

private int delta = 15;

public GradientShaderTextView(Context ctx)

{

this(ctx,null);

}

public GradientShaderTextView(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);

if (mViewWidth == 0) {

mViewWidth = getMeasuredWidth();

if (mViewWidth > 0) {

mPaint = getPaint();

String text = getText().toString();

// float textWidth = mPaint.measureText(text);

int size;

if(text.length()>0)

{

size = mViewWidth*2/text.length();

}else{

size = mViewWidth;

}

mLinearGradient = new LinearGradient(-size, 0, 0, 0,

new int[] { 0x33ffffff, 0xffffffff, 0x33ffffff },

new float[] { 0, 0.5f, 1 }, Shader.TileMode.CLAMP); //边缘融合

mPaint.setShader(mLinearGradient);

mGradientMatrix = new Matrix();

}

}

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

int length = Math.max(length(), 1);

if (mAnimating && mGradientMatrix != null) {

float mTextWidth = getPaint().measureText(getText().toString());

mTranslate += delta;

if (mTranslate > mTextWidth+1 || mTranslate<1) {

delta  = -delta;

}

mGradientMatrix.setTranslate(mTranslate, 0);

mLinearGradient.setLocalMatrix(mGradientMatrix);

postInvalidateDelayed(30);

}

}

}

第二种效果

import android.animation.ObjectAnimator;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.LinearGradient;

import android.graphics.Matrix;

import android.graphics.Paint;

import android.graphics.PorterDuff;

import android.graphics.PorterDuffXfermode;

import android.graphics.Rect;

import android.graphics.RectF;

import android.graphics.Shader;

import android.graphics.drawable.BitmapDrawable;

import android.util.AttributeSet;

import android.view.ActionMode;

import android.view.View;

import android.widget.TextView;

public class KTVTextView extends View {

private Paint mPaint;

private int delta = 15;

private float mTextHeight;

private float mTextWidth;

private PorterDuffXfermode xformode;

private String mText = "你是我生命里的一首歌";

public KTVTextView(Context ctx)

{

this(ctx,null);

}

public KTVTextView(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public KTVTextView(Context context,  AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

xformode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);

initViewAndDatas();

setOnClickListener(new View.OnClickListener(){

@Override

public void onClick(View v) {

postIndex = 0;

postInvalidate();

}

});

}

public void initViewAndDatas()

{

mPaint.setColor(Color.CYAN);

mPaint.setTextSize(40.0f);

mPaint.setStyle(Paint.Style.FILL_AND_STROKE);

mPaint.setXfermode(null);

mPaint.setTextAlign(Paint.Align.LEFT);

Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();

mTextHeight = fontMetrics.bottom-fontMetrics.descent-fontMetrics.ascent;

mTextWidth  = mPaint.measureText(mText);

//文字精确高度

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

//super.onMeasure(widthMeasureSpec, heightMeasureSpec);

int mWidth;

int mHeight;

/**

* 设置宽度

*/

int specMode = MeasureSpec.getMode(widthMeasureSpec);

int specSize = MeasureSpec.getSize(widthMeasureSpec);

if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate

{

mWidth = specSize;

}

else

{

// 由图片决定的宽

int desireByImg = getPaddingLeft() + getPaddingRight()

+ 380;

if (specMode == MeasureSpec.AT_MOST)// wrap_content

{

mWidth = Math.min(desireByImg, specSize);

} else

mWidth = desireByImg;

}

/***

* 设置高度

*/

specMode = MeasureSpec.getMode(heightMeasureSpec);

specSize = MeasureSpec.getSize(heightMeasureSpec);

if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate

{

mHeight = specSize;

} else

{

int desire = getPaddingTop() + getPaddingBottom()

+ 80;

if (specMode == MeasureSpec.AT_MOST)// wrap_content

{

mHeight = Math.min(desire, specSize);

} else

{

mHeight = desire;

}

}

setMeasuredDimension((int) mWidth, (int) mHeight);

}

private int postIndex;

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

int contentWidth = getWidth() - getPaddingLeft() - getPaddingRight();

int contentHeight = getHeight() - getPaddingTop() - getPaddingBottom();

Bitmap srcBitmap = Bitmap.createBitmap(getWidth(),getHeight(), Bitmap.Config.ARGB_8888);

Canvas srcCanvas = new Canvas(srcBitmap);

srcCanvas.drawText(mText, 0, getPaddingTop(), mPaint);

mPaint.setXfermode(xformode);

mPaint.setColor(Color.RED);

RectF rectF = new RectF(0,0,postIndex,mTextHeight);

srcCanvas.drawRect(rectF, mPaint);

canvas.drawBitmap(srcBitmap,getPaddingLeft(),getPaddingTop(), null);

initViewAndDatas();

if(postIndex

{

postIndex+=10;

postInvalidateDelayed(30);

}

}

}

注意:

文本绘制时必须和当前View保持同样的长宽尺寸,否则会出现文字变形问题

文本绘制的drawText(string,int x,int y,Paint paint);中的y值是基线位置

mTextHeight = fontMetrics.bottom-fontMetrics.descent-fontMetrics.ascent;//获得文本的高度

注意内容去的尺寸大小以及图片合成模式

注意LinearGradient的最后一个参数

自己去试试吧,我这些代码不够完善。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值