您的位置:首页 > 其它

自定义圆形、半圆形ProgressBar

2017-07-21 15:18 417 查看
最近在做的项目中遇到做圆形、半圆形ProgressBar,先分享给大家

主要用到类:

一、Android RectF类的构造函数参数说明

以下是API中的说明:

public RectF (float left, float top, float right, float bottom)

Added in API level 1

Create a new rectangle with the specified coordinates. Note: no range checking is performed, so the caller must ensure that left <= right and top <= bottom.

Parameters

left The X coordinate of the left side of the rectangle

top The Y coordinate of the top of the rectangle

right The X coordinate of the right side of the rectangle

bottom The Y coordinate of the bottom of the rectangle

比如new一个RecF类:

RectF rf1 = new RectF(100,100,200,200);

则在屏幕中的位置示意图为:

二、SweepGradient的说明与使用

主要实现圆形可颜色渐变进度条

public SweepGradient(float cx, float cy, int[] colors, float[] positions)

Parameters:

cx 渲染中心点x 坐标

cy 渲染中心y 点坐标

colors 围绕中心渲染的颜色数组,至少要有两种颜色值

positions 相对位置的颜色数组,可为null, 若为null,可为null,颜色沿渐变线均匀分布

public SweepGradient(float cx, float cy, int color0, int color1)

Parameters:

cx 渲染中心点x 坐标

cy 渲染中心点y 坐标

color0 起始渲染颜色

color1 结束渲染颜色

三、Canvas

public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)

oval :指定圆弧的外轮廓矩形区域。

startAngle: 圆弧起始角度,单位为度。

sweepAngle: 圆弧扫过的角度,顺时针方向,单位为度,从右中间开始为零度。

useCenter: 如果为True时,在绘制圆弧时将圆心包括在内,通常用来绘制扇形。关键是这个变量,下面将会详细介绍。

paint: 绘制圆弧的画板属性,如颜色,是否填充等。

Paint paint = new Paint();

paint.setStrokeWidth(20);

paint.setStyle(Paint.Style.STROKE);

paint.setColor(Color.BLUE);

float startAngle01 = 3;

float sweepAngle01 = 86;

RectF rect = new RectF(center - radius, center - radius, center

+ radius, center + radius);

canvas.drawArc(rect, startAngle01, sweepAngle01, true, paint);

当第4个参数为true的绘图如下 \

当是false的情况时,效果图如下 \这个参数为true时,会从圆弧的起始点到终点画两条边框

四、ValueAnimator**重点内容**

animator = ValueAnimator.ofInt(0, progress);

animator.setDuration(Math.abs(10 * progress));

animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

mProgress = (int) animation.getAnimatedValue();

postInvalidate();

}


});

animator.start();

实现源码:

public class RoundProgressView extends View {

private int mShaderWidth;

private int mProgressWidth;

private int mProgress = 0;

private int max = 100;

private Paint paint;

private int mHeight;
private int mWidth;
private ValueAnimator animator;
private int[] colors = new int[]{0xffffc700, 0xffffc700, 0xffffc700};
private float[] positions = new float[]{0.5f, 0.75f, 1};

public RoundProgressView(Context context) {
this(context, null);
}
public RoundProgressView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RoundProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);

paint = new Paint();

TypedArray mTypedArray =
context.obtainStyledAttributes(attrs, R.styleable.RoundProgressView);

mProgress = mTypedArray.getInteger(R.styleable.RoundProgressView_progressValue, 0);
mShaderWidth = mTypedArray.getDimensionPixelSize(R.styleable.RoundProgressView_shaderWidth, 26);
mProgressWidth = mTypedArray.getDimensionPixelSize(R.styleable.RoundProgressView_progressWidth, 18);

mTypedArray.recycle();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int center = getWidth() / 2;
int radius = (int) (getWidth() / 2 - mProgressWidth / 2 - mShaderWidth);
RectF oval = new RectF(center - radius, center - radius, center + radius, center+ radius);

// 画主进度圆环
if (mProgress > 0) {
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(mProgressWidth);
paint.setAntiAlias(true);
paint.setStrokeCap(Paint.Cap.ROUND);

float rate = mProgress / (float) max;

paint.setShader(new SweepGradient(getWidth()/2, getHeight()/2, colors, positions));
canvas.rotate(0, getWidth()/2, getHeight()/2);
canvas.drawArc(oval, 165, rate * 210, false, paint);
}}
public void setProgressWithAnim(final int progress) {
if (animator != null) {
animator.cancel();
}
animator = ValueAnimator.ofInt(0, progress);
animator.setDuration(Math.abs(10 * progress));
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mProgress = (int) animation.getAnimatedValue();
postInvalidate();

}});
animator.start();
}
public void setProgress(int progress) {
if (animator != null) {
animator.cancel();
}mProgress = progress;
postInvalidate();
}
@TargetApi(Build.VERSION_CODES.KITKAT)
public void pause() {
if (animator != null && animator.isRunning()) {
animator.pause();
}}
@TargetApi(Build.VERSION_CODES.KITKAT)
public void resume() {
if (animator != null && animator.isPaused()) {
animator.resume();
}}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthSpecMode == MeasureSpec.EXACTLY || widthSpecMode == MeasureSpec.AT_MOST) {
mWidth = widthSpecSize;
} else {
mWidth = 0;
}if (heightSpecMode == MeasureSpec.AT_MOST || heightSpecMode == MeasureSpec.UNSPECIFIED) {
mHeight = dipToPx(15);
} else {
mHeight = heightSpecSize;
}setMeasuredDimension(mWidth, mHeight);
}
private int dipToPx(int dip) {
float scale = getContext().getResources().getDisplayMetrics().density;
return (int) (dip * scale + 0.5f * (dip >= 0 ? 1 : -1));
}


}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: