本着写文即学习的态度,记录下自定义一款超简单仿QQ步数加载控件,话不多数先看图。
一,特性:
1,外圈大圆、进度圆和数字显示的颜色均可以自定义
2,设置最大值和当前值
3,设置加载持续时间
二,实现:
1,画外圈大圆
2,画内圈进度圆
3,画文字
在第二步与第三步要根据设置的最大值和当前值动态持续更新进行绘画,这里我使用valueAnimation获取中间值。
- 自定义属性
<declare-styleable name="CircleProgressView">
<attr name="circle_process_stroke_width" format="dimension" />
<attr name="circle_process_stroke_color" format="color" />
<attr name="circle_process_progress_color" format="color" />
<attr name="circle_process_text_color" format="color" />
<attr name="circle_process_text_size" format="dimension" />
<attr name="circle_process_duration" format="dimension"/>
</declare-styleable>
- 自定义CircleProgressView继承自view,获取属性值
private void initAttrs(AttributeSet attrs) {
TypedArray attribute = getContext().obtainStyledAttributes(attrs, R.styleable.CircleProgressView);
mCircleColor = attribute.getColor(R.styleable.CircleProgressView_circle_process_stroke_color, Color.BLUE);
mProgressColor = attribute.getColor(R.styleable.CircleProgressView_circle_process_progress_color, Color.RED);
mRoundWidth = (int) attribute.getDimension(R.styleable.CircleProgressView_circle_process_stroke_width, 1f);
mTextColor = attribute.getColor(R.styleable.CircleProgressView_circle_process_text_color, 0XFFFC00D1);
mTextSize = (int) attribute.getDimension(R.styleable.CircleProgressView_circle_process_text_size, 20f);
mDuration = (long) attribute.getDimension(R.styleable.CircleProgressView_circle_process_duration,2000f);
attribute.recycle();
}
- 测量
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mViewWidth = MeasureSpec.getSize(widthMeasureSpec);
mViewHeight = MeasureSpec.getSize(heightMeasureSpec);
centerX = mViewWidth / 2;
centerY = mViewHeight / 2;
radius = Math.min(centerX, centerY) - mRoundWidth;//半径
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
- 画外圈大圆
//画外圈大圆
mPaint.setColor(mCircleColor);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(mRoundWidth);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeJoin(Paint.Join.ROUND);
canvas.drawCircle(centerX, centerY, radius, mPaint);
- 画进度圆
//根据比值画进度圆
mPaint.setColor(mProgressColor);
RectF rectF = new RectF(centerX - radius, centerY - radius, centerX + radius, centerY + radius);
float curRadius = process * 360;
canvas.drawArc(rectF, 90f, curRadius, false, mPaint);
- 画数字
//根据比值画文字
mPaint.reset();
mPaint.setAntiAlias(true);
mPaint.setColor(mTextColor);
mPaint.setTextSize(mTextSize);
String text = (int) (process * mMaxNum) + "/" + (int) mMaxNum;
Rect textBound = new Rect();
mPaint.getTextBounds(text, 0, text.length(), textBound);
int textStart = (mViewWidth - textBound.width()) / 2;
Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
int baseLine = (int) (mViewHeight / 2 + (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom);
canvas.drawText(text, textStart, baseLine, mPaint);
- 还有一个最重要的方法,开始动画,产生中间值,计算比值
/**
* 开始动画
*
* @param maxNum 最大值
* @param curNum 当前值
*/
public synchronized void start(final float maxNum, float curNum) {
if (maxNum <= 0)
throw new IllegalArgumentException("maxNum 必须大于0");
if (curNum < 0)
throw new IllegalArgumentException("curNum 不能小于0");
if (curNum > maxNum)
throw new IllegalArgumentException("curNum 不能大于maxNum");
mMaxNum = maxNum;
ValueAnimator animator = ValueAnimator.ofFloat(0, curNum);
animator.setDuration(mDuration);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
//计算得到比值
process = value / maxNum;
invalidate();
}
});
animator.start();
}
至此功能已经初步完成了,可以另外提供一些方法方便使用
/**
* 设置描边宽度
*
* @param width
*/
public synchronized void setRoundWidth(int width) {
if (width > 0) {
mRoundWidth = width;
}
}
/**
* 设置动画执行时间,单位ms
* @param duration
*/
public synchronized void setDuration(long duration) {
if (duration > 0) {
mDuration = duration;
}
}
/**
* 设置外圈大圆颜色
*
* @param color
*/
public synchronized void setCircleColor(int color) {
mCircleColor = color;
}
/**
* 设置进度圆颜色
*
* @param color
*/
public synchronized void setProgressColor(int color) {
mProgressColor = color;
}
/**
* 设置文字颜色
*
* @param color
*/
public synchronized void setTextColor(int color) {
mTextColor = color;
}
大功告成,简单的功能实现,希望能抛砖引玉啦!