自定义ProgressBar,SeekBar 第二篇
上一篇链接:http://blog.csdn.net/zhangxiaofan_/article/details/51566455
看到一个网上的进度栏写的挺漂亮,我也来试试吧
一言不合我就贴代码!
效果图如下:
目前做出的效果
定义如下:
private final int COLOR_RED = 0xFFE32F4F;//源的颜色,红
private final int COLOR_GREY = 0xFF666666;//目标的颜色,灰
private RectF mRectFBg;//目标Rect
private RectF mRectFSrc;//源Rect
private RectF mRectRound;//圆角矩形Rect
private Paint mPaint;//画笔
private Paint mRoundPaint;//画笔
private Path mDeltaPath;//三角形路径
private int RADIUS_BIG;//空心的外圆半径
private int RADIUS_SMALL;//实心的内圆半径
private int LINE_HEIGHT;//进度线高度
private int ROUND_RECT_WIDTH;//圆角矩形的宽度
private int ROUND_RECT_HEIGHT;//圆角矩形的宽度
private int DELTA_WIDTH;//三角形宽度
private int DELTA_HEIGHT;//三角形高度
private int DELTA_SPACE_HEIGHT;//三角形间隔高度
private float progress;//进度
private float progressText;//动态文字进度
private ProgressAnimation animation;//进度动画
初始化
public ProgressLine2(Context context) {
super(context);
init();
}
public ProgressLine2(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mRoundPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
mRoundPaint.setTextSize(30);
}
onMeasure中
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int measuredHeight = getMeasuredHeight();
int measuredWidth = getMeasuredWidth();
if (mRectFBg == null) {
RADIUS_BIG = (int) (10 * getResources().getDisplayMetrics().density + 0.5f);
RADIUS_SMALL = RADIUS_BIG >> 1;
LINE_HEIGHT = (int) (10 * getResources().getDisplayMetrics().density + 0.5f);
Paint.FontMetrics fm = mRoundPaint.getFontMetrics();
ROUND_RECT_WIDTH = (int) (mRoundPaint.measureText("100") * 1.5f);
ROUND_RECT_HEIGHT = (int) ((fm.bottom - fm.top) * 1.5f);
DELTA_WIDTH = ROUND_RECT_WIDTH / 3;
DELTA_HEIGHT = ROUND_RECT_WIDTH / 5;
DELTA_SPACE_HEIGHT = (int) (LINE_HEIGHT/2.5f);
mPaint.setStrokeWidth(LINE_HEIGHT);
mRectFBg = new RectF(RADIUS_BIG - RADIUS_SMALL, measuredHeight / 2, measuredWidth - (RADIUS_BIG - RADIUS_SMALL), measuredHeight / 2 + LINE_HEIGHT / 2);
mRectFSrc = new RectF(mRectFBg);
mRectFSrc.right = 0;
mRectRound = new RectF(RADIUS_BIG - RADIUS_SMALL, measuredHeight / 2 - ROUND_RECT_HEIGHT - LINE_HEIGHT / 2 - DELTA_HEIGHT-DELTA_SPACE_HEIGHT, ROUND_RECT_WIDTH + RADIUS_BIG - RADIUS_SMALL, measuredHeight / 2 - LINE_HEIGHT / 2 - DELTA_HEIGHT-DELTA_SPACE_HEIGHT);
mDeltaPath = new Path();
// DELTA_HEIGHT/4 是为了让这个三角形往上偏移一点,让一部分重叠在一起
mDeltaPath.moveTo(mRectRound.left, mRectRound.bottom-DELTA_HEIGHT/4);
mDeltaPath.lineTo(mRectRound.left + DELTA_WIDTH, mRectRound.bottom-DELTA_HEIGHT/4);
mDeltaPath.lineTo((mRectRound.left + DELTA_WIDTH) / 2, mRectRound.bottom -DELTA_HEIGHT/4+ DELTA_HEIGHT);
mDeltaPath.close();
}
}
onDraw中
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(0x33333333);
mPaint.setColor(COLOR_GREY);
canvas.drawLine(mRectFBg.left, mRectFBg.top, mRectFBg.right, getHeight() / 2, mPaint);//绘制目标
mPaint.setColor(COLOR_RED);
canvas.drawLine(0, getHeight() / 2, mRectFSrc.right, mRectFSrc.top, mPaint);//绘制源
mRoundPaint.setColor(0xFFFFFFFF);
canvas.drawRoundRect(mRectRound, 10, 10, mRoundPaint);//矩形框
canvas.drawPath(mDeltaPath, mRoundPaint);//三角形
mRoundPaint.setColor(0xFF000000);
String str = String.valueOf((int) (progressText * 100));
Paint.FontMetrics fm = mRoundPaint.getFontMetrics();
canvas.drawText(str, mRectRound.left + (ROUND_RECT_WIDTH - mRoundPaint.measureText(str)) / 2, mRectRound.bottom - (ROUND_RECT_HEIGHT - (fm.leading - fm.ascent)) / 2, mRoundPaint);//文字
}
设置进度的方法
public void setProgress(float progress) {
this.progress = progress;
if (animation == null) {
animation = new ProgressAnimation();
animation.setDuration(3000);
animation.setInterpolator(new AccelerateDecelerateInterpolator());
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
}
startAnimation(animation);
}
主要的计算逻辑在这个动画类中
private class ProgressAnimation extends Animation {
float offsetX;
float offsetY;
public ProgressAnimation() {
offsetY = mRectRound.bottom + ROUND_RECT_WIDTH / 6;
offsetX = RADIUS_BIG - RADIUS_SMALL;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
progressText = interpolatedTime * progress;
mRectFSrc.right = (mRectFBg.right - RADIUS_SMALL * 2) * interpolatedTime * progress;
mRectFBg.left = mRectFSrc.right;
mRectRound.left = RADIUS_BIG - RADIUS_SMALL + (getWidth() - ROUND_RECT_WIDTH) * interpolatedTime;
mRectRound.right = RADIUS_BIG - RADIUS_SMALL + (getWidth() - ROUND_RECT_WIDTH) * interpolatedTime + ROUND_RECT_WIDTH;
if (interpolatedTime < 0.4f) {
interpolatedTime *= 10.0f / 4;
mRectFSrc.top = getHeight() / 2 + (getHeight() - LINE_HEIGHT) / 2 * interpolatedTime;
mRectFBg.top = getHeight() / 2 + (getHeight() - LINE_HEIGHT) / 2 * interpolatedTime;
mRectRound.top = getHeight() / 2 - ROUND_RECT_HEIGHT - LINE_HEIGHT / 2 - DELTA_HEIGHT-DELTA_SPACE_HEIGHT + getHeight() / 2 * interpolatedTime;
mRectRound.bottom = getHeight() / 2 - LINE_HEIGHT / 2 - DELTA_HEIGHT-DELTA_SPACE_HEIGHT + getHeight() / 2 * interpolatedTime;
mDeltaPath.offset(mRectRound.left - offsetX, mRectRound.bottom + ROUND_RECT_WIDTH / 6- offsetY);
offsetX = mRectRound.left;
offsetY = mRectRound.bottom + ROUND_RECT_WIDTH / 6;
} else {
interpolatedTime = (interpolatedTime - 0.4f) * 10.0f / 6;
mRectFSrc.top = getHeight() - LINE_HEIGHT / 2 - (getHeight() - LINE_HEIGHT) / 2 * interpolatedTime;
mRectFBg.top = getHeight() - LINE_HEIGHT / 2 - (getHeight() - LINE_HEIGHT) / 2 * interpolatedTime;
mRectRound.top = getHeight() - ROUND_RECT_HEIGHT - LINE_HEIGHT / 2 - DELTA_HEIGHT -DELTA_SPACE_HEIGHT- (getHeight() / 2) * interpolatedTime;
mRectRound.bottom = getHeight() - LINE_HEIGHT / 2 - DELTA_HEIGHT -DELTA_SPACE_HEIGHT- getHeight() / 2 * interpolatedTime;
mDeltaPath.offset(mRectRound.left - offsetX, mRectRound.bottom + ROUND_RECT_WIDTH / 6- offsetY);
offsetX = mRectRound.left;
offsetY = mRectRound.bottom + ROUND_RECT_WIDTH / 6;
}
invalidate();
}
}
最后总结:
这个其实还没有完全完成,移动的时候 矩形下面的三角形偏移处理没有做处理,和原图的效果不一致,且在移动中整个矩形和底下的线的纵轴偏移没有保持不变.
只是我已经对这个类不感兴趣了,剩余的你们自己完成吧