今天实现的是字体颜色渐变,且是从左到右逐渐改变, 具体:随着ViewPager的滑动,左边标题字体的颜色从左到右逐渐由黑变红,右边的标题字体从左到右逐渐变红。效果如下图:(如果对你有帮助,麻烦写下评论,这对我将是一种激励!)
这里主要用到的是,canvas.clipRect(left, 0, right, mHeight);这个方法,截取我们需要显示的部分,
所以要达到上面的效果,文本描绘了两次,黑色文本与红色文本,只不过左边的标题截取了黑色文本的前半部和红色文本的后半部组合在一起;右边的标题截取了黑色文本的后半部与红色文本的前半部组合在一起。
下面代码走起:
先自定义:ColorTrackView
老生常谈一下:自定义步骤,1,自定义属性;2,在构造方法中获取构造属性;3,重写onMeasure;4,重写onDraw方法
在这里就直接贴出自定义属性文件,和自定义类文件
自定义属性:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="mtext" format="string"></attr>
<attr name="mtextsize" format="dimension"></attr>
<attr name="innercolor" format="color"></attr>
<attr name="outcolor" format="color"></attr>
<attr name="progress" format="float"></attr>
<attr name="mdirection">
<enum name="left" value="0"></enum>
<enum name="right" value="1"></enum>
</attr>
<declare-styleable name="ColorTrackView">
<attr name="mtext"></attr>
<attr name="mtextsize"></attr>
<attr name="innercolor"></attr>
<attr name="outcolor"></attr>
<attr name="progress"></attr>
<attr name="mdirection"></attr>
</declare-styleable>
</resources>
自定义类文件:
package com.wang.demo_colorchange.view;
import com.wang.demo_colorchange.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
public class ColorTrackView extends View {
// 文本内容
private String mtext;
// 文本型号
private int mtextSize;
// 宽度
private int mWidth;
// 高度
private int mHeight;
// 底层颜色
private int mInnerColor;
// 外层颜色
private int mOutColor;
// 覆盖比例
private float mProgress;
// 朝向
private final int Direction_Left = 0;
private final int Direction_Right = 1;
private int mDirection = Direction_Left;
private Paint mPaint;
/**
* 控制文本范围的矩阵
*/
private Rect mtextBound;
/**
* 文本的宽度,mtextBound 略小与mTextWidth
*/
private float mTextWidth;
public ColorTrackView(Context context) {
this(context, null, 0);
}
public ColorTrackView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
//获取自定义属性
public ColorTrackView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ColorTrackView);
int count = typedArray.getIndexCount();
for (int i = 0; i < count; i++) {
int attr = typedArray.getIndex(i);
switch (attr) {
case R.styleable.ColorTrackView_mtext:
mtext = typedArray.getString(attr);
break;
case R.styleable.ColorTrackView_mtextsize:
mtextSize = (int) typedArray
.getDimension(attr, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
16, context.getResources().getDisplayMetrics()));
break;
case R.styleable.ColorTrackView_progress:
mProgress = typedArray.getFloat(attr, 0);
break;
case R.styleable.ColorTrackView_innercolor:
mInnerColor = typedArray.getColor(attr, 0xffff0000);
break;
case R.styleable.ColorTrackView_outcolor:
mOutColor = typedArray.getColor(attr, 0xff0000);
break;
case R.styleable.ColorTrackView_mdirection:
mDirection = typedArray.getInteger(attr, 0);
break;
}
}
typedArray.recycle();
mtextBound = new Rect();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setTextSize(mtextSize);
mPaint.getTextBounds(mtext, 0, mtext.length(), mtextBound);
mTextWidth = mPaint.measureText(mtext);//这种方法得到的宽度更为准确
// Log.i("wangsongbin",
// "textwidth:"+textWidth+" bound.width():"+mtextBound.width());
}
//合理的调整控件的高宽
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width;
int height;
int mode = MeasureSpec.getMode(widthMeasureSpec);
int size = MeasureSpec.getSize(widthMeasureSpec);
if (mode == MeasureSpec.EXACTLY) {
width = size + getPaddingLeft() + getPaddingRight();
} else {
width = (int) (mTextWidth + getPaddingLeft() + getPaddingRight());
}
mode = MeasureSpec.getMode(heightMeasureSpec);
size = MeasureSpec.getSize(heightMeasureSpec);
if (mode == MeasureSpec.EXACTLY) {
height = size + getPaddingTop() + getPaddingBottom();
} else {
height = mtextBound.height() + getPaddingBottom() + getPaddingTop();
}
setMeasuredDimension(width, height);
mWidth = getMeasuredWidth();
mHeight = getMeasuredHeight();
}
//绘制文本
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mDirection == Direction_Left) {
float left = 0;
float right = mWidth * 1.0f / 2 - mTextWidth * 1.0f / 2 + mProgress * 1.0f * mTextWidth;
drawText(canvas, left, right, mOutColor);
left = right;
right = mWidth;
drawText(canvas, left, right, mInnerColor);
} else {
float left = 0;
float right = mWidth * 1.0f / 2 - mTextWidth * 1.0f / 2 + mProgress * 1.0f * mTextWidth;
drawText(canvas, left, right, mInnerColor);
left = right;
right = mWidth;
drawText(canvas, left, right, mOutColor);
}
}
private void drawText(Canvas canvas, float left, float right, int color) {
mPaint.setColor(color);
canvas.save(Canvas.CLIP_SAVE_FLAG);
canvas.clipRect(left, 0, right, mHeight);//截取自定想要的矩形部分
canvas.drawText(mtext, mWidth * 1.0f / 2 - mtextBound.width() * 1.0f / 2, mHeight * 1.0f
/ 2 + mtextBound.height() * 1.0f / 2, mPaint);
canvas.restore();
}
//设置截取的前面部分所占的比例
public void setProgress(float progress) {
mProgress = progress;
invalidate();
}
/**
* 设置方向
*
* @param direction
*/
public void setDirection(int direction) {
mDirection = direction;
}
}
接下来就是调用:主要是监听ViewPager的滑动,动态改变ColorTrackView的文本截取范围。核心就是下面的监听器代码,其余都是大家写烂了的东西!就不浪费篇章了!
class MyViewPagerChangeListener implements ViewPager.OnPageChangeListener{
@Override
public void onPageScrollStateChanged(int arg0) {
}
@Override
public void onPageScrolled(int position, float positionOffset, int arg2) {
if(positionOffset>0){
ct_views[position].setDirection(0);
ct_views[position].setProgress(positionOffset);
ct_views[position+1].setDirection(1);
ct_views[position+1].setProgress(positionOffset);
}
}
@Override
public void onPageSelected(int position) {
}
}
源码下载