自定义刻度尺进度条代码记录下
package com.myf.ruler;
import android.animation.TimeAnimator;
import android.animation.TimeAnimator.TimeListener;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/**
* 刻度进度条
* @author Mengyf
*
*/
@SuppressLint({ "NewApi", "DefaultLocale" })
public class RulerProgressBar extends View{
/** 绘制刻度的画笔 */
private Paint mPaintRuler;
/** 绘制刻度尺颜色 */
private int mRulerColor = Color.RED;
/** 设置刻度之间的距离 */
private int mRulerDistance = 5;
/** 绘制刻度尺高度 */
private int mRulerHeight = 100;
/** 绘制刻度尺宽度 */
private int mRulerWidth;
/** 进度值 */
private int mProgress;
/** 最大值 */
private int mMax = 100;
/** 设置托块的宽度 */
private float mRulerThumbWidth = 2;
/** 设置托块的高度 */
private float mRulerThumbHeight = 100;
/** 设置拖块的颜色 */
private int mRulerThumbColor = Color.BLUE;
/** 动画 */
private TimeAnimator mTimeAnimator;
/** 拖块的偏移量 */
private float mThumbOffset = 0;
/** 记录目标偏移量 */
private float mTargetOffset;
/** 设置动画执行速度 */
private float mAnimSpeed = 1f;
/** 设置文字大小 */
private float mTextSize = 30;
private IOnProgressChangeListener mL;
/** 记录上一次的值 */
private int mLastProgress = -1;
/** 是否显示文本 */
private boolean isShowText = false;
/**
* 圆形进度
* @param l
*/
public void setOnProgressChangeListener(IOnProgressChangeListener l) {
mL = l;
}
/**
* 进度值改变监听
* @author ZH-SW-Mengyf
*
*/
public interface IOnProgressChangeListener{
/**
* 环形进度条
* @param rectangularView
* @param progress
*/
void progressChange(RulerProgressBar rulerProgressBar, int progress,boolean isAniming);
}
/**
* 通知进度改变
* @param progress
* @param isAniming
*/
private void notifyProgressChange(int progress,boolean isAniming) {
if (mL != null) {
if (mLastProgress != progress||!isAniming) {
mLastProgress = progress;
mL.progressChange(this, progress, isAniming);
}
}
}
public RulerProgressBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public RulerProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public RulerProgressBar(Context context) {
super(context);
init(context);
}
private void init(Context context){
initPaintRuler();
setRulerColor(Color.RED);
setRulerDistance(10);
setMax(50);
setRulerHeight(100);
setRulerWidth(3);
setRulerThumbWidth(3);
setRulerThumbColor(Color.BLUE);
setRulerThumbHeight(100);
setProgress(21);
setAnimSpeed(2);
setShowText(true);
}
/**
* 初始化刻度画笔
*/
private void initPaintRuler() {
mPaintRuler = new Paint();
mPaintRuler.setAntiAlias(true);
}
/**
* 绘制线颜色
* @param lineColor
*/
private void setRulerColor(int rulerColor) {
mRulerColor = rulerColor;
invalidate();
}
/**
* 设置刻度之间的距离
*/
public void setRulerDistance(int rulerDistance) {
mRulerDistance = rulerDistance;
invalidate();
}
/**
* 获取刻度之间的距离
*/
public int getRulerDistance() {
return mRulerDistance;
}
/**
* 绘制刻度尺高度
*/
public void setRulerHeight(int rulerHeight) {
mRulerHeight = rulerHeight;
invalidate();
}
/**
* 绘制刻度尺线宽度
*/
public void setRulerWidth(int rulerWidth) {
mRulerWidth = rulerWidth;
invalidate();
}
/**
* 获取刻度尺线宽度
* @return
*/
public int getRulerWidth() {
return mRulerWidth;
}
/**
* 设置动画执行的速度
*
* @param animSpeed
*/
public void setAnimSpeed(float animSpeed) {
if (animSpeed < 0.1) {
animSpeed = 0.1f;
}
mAnimSpeed = animSpeed;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int minimumWidth = getSuggestedMinimumWidth();
final int minimumHeight = getSuggestedMinimumHeight();
int width = measureWidth(minimumWidth, widthMeasureSpec);
int height = measureHeight(minimumHeight, heightMeasureSpec);
setMeasuredDimension(width, height);
}
/**
* 测量宽度
* @param defaultWidth
* @param measureSpec
* @return
*/
private int measureWidth(int defaultWidth, int measureSpec) {
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
switch (specMode) {
case MeasureSpec.AT_MOST:
defaultWidth = mRulerDistance * getMax() + mRulerWidth +getPaddingStart()+getPaddingEnd();
break;
case MeasureSpec.EXACTLY:
defaultWidth = specSize;
break;
case MeasureSpec.UNSPECIFIED:
defaultWidth = Math.max(defaultWidth, specSize);
}
return defaultWidth;
}
/**
* 测量高度
* @param defaultHeight
* @param measureSpec
* @return
*/
private int measureHeight(int defaultHeight, int measureSpec) {
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
switch (specMode) {
case MeasureSpec.AT_MOST:
defaultHeight = mRulerHeight;
break;
case MeasureSpec.EXACTLY:
defaultHeight = specSize;
break;
case MeasureSpec.UNSPECIFIED:
defaultHeight = Math.max(defaultHeight, specSize);
break;
}
return defaultHeight;
}
/**
* 绘制刻度拖块颜色
* @param rulerThumbColor
*/
private void setRulerThumbColor(int rulerThumbColor) {
mRulerThumbColor = rulerThumbColor;
invalidate();
}
/**
* 绘制刻度拖块宽度
* @param rulerThumbWidth
*/
private void setRulerThumbWidth(float rulerThumbWidth) {
mRulerThumbWidth = rulerThumbWidth;
invalidate();
}
/**
* 绘制刻度拖块高度
* @param rulerThumbWidth
*/
private void setRulerThumbHeight(float rulerThumbHeight) {
mRulerThumbHeight = rulerThumbHeight;
invalidate();
}
/**
* 设置最大值
*
* @param max
*/
public void setMax(int max) {
if (max < 0) {
max = 0;
}
if (max != mMax) {
mMax = max;
postInvalidate();
if (mProgress > max) {
mProgress = max;
}
refreshProgress(mProgress, false);
}
}
/**
* 或者最大值
*
* @return
*/
public int getMax() {
return mMax;
}
/**
* 设置进度值
* @param progress
*/
public void setProgress(int progress) {
setProgress(progress, false, true);
}
/**
* 设置进度值
* @param progress
*/
public void setProgress(int progress ,boolean anim) {
setProgress(progress, anim, true);
}
/**
* 设置进度
*
* @param progress
* @param fromUser
* @param refreshProgress
*/
public void setProgress(int progress, boolean anim, boolean refreshProgress) {
if (progress < 0) {
progress = 0;
}
if (progress > mMax) {
progress = mMax;
}
if (progress != mProgress || refreshProgress) {
mProgress = progress;
if (refreshProgress) {
refreshProgress(mProgress, anim);
}
}
}
/**
* 获取进度
*
* @return
*/
public int getProgress() {
return mProgress;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawRuler(canvas);
drawRulerThumb(canvas);
}
/**
* 绘制刻度
* @param canvas
*/
private void drawRuler(Canvas canvas) {
mPaintRuler.setColor(mRulerColor);
mPaintRuler.setStrokeWidth(mRulerWidth);
mPaintRuler.setStrokeCap(Paint.Cap.ROUND);
for (int i = 0; i <= getMax(); i++) {
float rulerPosition = getRulerPosition(i);
float startX = rulerPosition + getPaddingStart();
float startY = 0 + getPaddingTop();
float stopX = rulerPosition + getPaddingStart();
float stopY = mRulerHeight - getPaddingBottom();
if (i % 10 == 0) {
stopY = mRulerHeight / 1.5f;
canvas.drawLine(startX, startY, stopX, stopY, mPaintRuler);
drawRulerText(canvas, i, startX, stopY);
}else if(i % 5 == 0){
stopY = mRulerHeight / 2.0f;
canvas.drawLine(startX, startY, stopX, stopY, mPaintRuler);
}else{
stopY = mRulerHeight / 3f;
canvas.drawLine(startX, startY, stopX, stopY, mPaintRuler);
}
}
}
/**
* 设置文字大小
* @param textSize
*/
public void setTextSize(float textSize ) {
mTextSize = textSize;
invalidate();
}
/**
* 显示文本
* @param showText
*/
public void setShowText(boolean showText) {
isShowText = showText;
setPadding((int)mTextSize, getPaddingTop(), (int)mTextSize , getPaddingBottom());
invalidate();
}
/**
* 绘制刻度尺文字
* @param canvas
*/
private void drawRulerText(Canvas canvas,int i, float startX, float startY) {
if (isShowText) {
String text = String.valueOf(i);
mPaintRuler.setTextSize(mTextSize);
float valueW = mPaintRuler.measureText(text);
canvas.drawText(text, startX - valueW / 2, startY + mTextSize, mPaintRuler);
}
}
/**
* 获取每个刻度的位置
* @param i
* @return
*/
private float getRulerPosition(int i) {
return mRulerWidth / 2 + i * mRulerDistance;
}
/**
* 绘制刻度拖块
* @param canvas
*/
private void drawRulerThumb(Canvas canvas) {
mPaintRuler.setColor(mRulerThumbColor);
mPaintRuler.setStrokeWidth(mRulerThumbWidth);
mPaintRuler.setStrokeCap(Paint.Cap.ROUND);
float startX = mThumbOffset + getPaddingStart();
float startY = 0 + getPaddingTop();
float stopX = mThumbOffset + getPaddingStart();
float stopY = mRulerThumbHeight - getPaddingBottom();
canvas.drawLine(startX, startY, stopX, stopY, mPaintRuler);
}
/**
* 获取每个刻度的位置
* @param i
* @return
*/
private float getRulerThumbPosition(int i) {
return mRulerThumbWidth / 2 + i * mRulerDistance;
}
/**
* 刷新进度值
*
* @param progress
*/
protected void refreshProgress(int progress , boolean isAnim) {
if (isAnim) {
setAnim(getRulerThumbPosition(progress));
}else{
mProgress = progress;
refreshThumbOffset(getRulerThumbPosition(progress));
notifyProgressChange(mProgress, false);
}
}
/**
* 刷新托快的偏移量
* @param offset
*/
protected void refreshThumbOffset(float offset) {
stopAnim();
mThumbOffset = getThumbValidOffset(offset);
invalidate();
}
/**
* 设置动画效果
* @param offset
*/
@SuppressLint("NewApi")
private void setAnim(final float offset) {
mTargetOffset = offset;
if (mTimeAnimator == null) {
mTimeAnimator = new TimeAnimator();
mTimeAnimator.setTimeListener(new TimeListener() {
@Override
public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) {
//意思就是传递进来的mTargetOffset值如果大于现有的mThumbOffset,那么就应该自增达到mTargetOffset
if (mTargetOffset > mThumbOffset) {
mThumbOffset = getTempOffset(true);
mProgress = (int) (mThumbOffset / mRulerDistance);
notifyProgressChange(mProgress, true);
//当mThumbOffset在进行自增,等于或者大于了目标值mTargetOffset,就应该停止
if (mTargetOffset <= mThumbOffset) {
mThumbOffset = mTargetOffset;
notifyProgressChange(mProgress, false);
stopAnim();
}
}
//意思就是传递进来的mTargetOffset值如果小于现有的mThumbOffset,那么就应该自减达到mTargetOffset
else if (mTargetOffset < mThumbOffset) {
mThumbOffset = getTempOffset(false);
mProgress = (int) (mThumbOffset / mRulerDistance);
notifyProgressChange(mProgress, true);
//当mThumbOffset在进行自减,等于或者小于了目标值mTargetOffset,就应该停止
if (mTargetOffset >= mThumbOffset) {
mThumbOffset = mTargetOffset;
notifyProgressChange(mProgress, false);
stopAnim();
}
}else{
stopAnim();
}
postInvalidate();
}
});
}
startAnim();
}
/**
* 获取临时,自增,或者自减偏移量
* @param isAdd
* @return
*/
private float getTempOffset(boolean isAdd) {
float offset;
if (isAdd) {
offset = mThumbOffset + mAnimSpeed;
} else {
offset = mThumbOffset - mAnimSpeed;
}
offset = getThumbValidOffset(offset);
return offset;
}
/**
* 获取有效的偏移量
* @return
*/
protected float getThumbValidOffset(float offset) {
int maxOffset = (int) (mMax * mRulerDistance + mRulerThumbWidth);
if (offset > maxOffset) {
offset = maxOffset;
}
if (offset < 0) {
offset = 0;
}
return offset;
}
/**
* 开机动画
*/
private void startAnim() {
if (mTimeAnimator != null && !mTimeAnimator.isStarted()) {
mTimeAnimator.start();
}
}
/**
* 结束动画
*/
private void stopAnim() {
if (mTimeAnimator != null && mTimeAnimator.isStarted()) {
mTimeAnimator.end();
}
}
}