import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
/**
* 圆形进度条
* Created by WSJ on 2016/12/15.
*/
public class CircleProgressDrawable extends Drawable {
private static final String TAG = "CircleProgressDrawable";
// 画笔.
private Paint mPaint;
// 当前进度.
private int mCurProgress;
// 总进度.
private int mMaxProgress;
// 开始角度.
private int mStartAngle;
// 旋转方向, 顺时针,逆时针.
private int mOritation;
// 圆环宽度.
private int mRingWidth;
/**
* 进度条开始位置.
*/
public interface StartPointType {
// 右
public static final int START_ANGLE_RIGHT = 0;
// 下
public static final int START_ANGLE_BOTTOM = 90;
// 左
public static final int START_ANGLE_LEFT = 180;
// 上
public static final int START_ANGLE_TOP = 270;
}
/**
* 进度条方向
*/
public interface ProgressOrientation {
// 顺时针.
public static final int PROGRESS_ORITATION_CLOCKWISE = 0x00;
// 逆时针.
public static final int PROGRESS_ORITAITON_ANTICLOCKWISE = 0x01;
}
public void setOrientation(int orientation){
if (orientation == ProgressOrientation.PROGRESS_ORITAITON_ANTICLOCKWISE || orientation == ProgressOrientation.PROGRESS_ORITATION_CLOCKWISE){
mOritation = orientation;
}else {
throw new RuntimeException("Orientation value must be from interface ProgressOrientation !");
}
}
public CircleProgressDrawable(int maxProgress, int ringWidth, int ringColor,int startAngle){
mMaxProgress = maxProgress;
mCurProgress = 0;
mStartAngle = startAngle;
mRingWidth = ringWidth;
// 默认是逆时针方向.
mOritation = ProgressOrientation.PROGRESS_ORITAITON_ANTICLOCKWISE;
mPaint = new Paint();
// 描边
mPaint.setStyle(Paint.Style.STROKE);
// 设置颜色
mPaint.setColor(ringColor);
// 设置抗锯齿
mPaint.setAntiAlias(true);
// 设置圆环宽度
mPaint.setStrokeWidth(mRingWidth);
// 设置圆角
mPaint.setStrokeCap(Paint.Cap.ROUND);
}
public int getCurProgress(){
return mCurProgress;
}
/**
* 设置进度百分比 .
* @param curProgress 当前进度.
*/
public void setCurProgress(int curProgress){
// 赋值
if (mOritation == ProgressOrientation.PROGRESS_ORITATION_CLOCKWISE){
// 顺时针.
mCurProgress = curProgress > mMaxProgress ? mMaxProgress : curProgress;
}else {
// 逆时针
mCurProgress = -(curProgress > mMaxProgress ? mMaxProgress : curProgress);
}
// 重绘
invalidateSelf();
}
@Override
public void draw(Canvas canvas) {
// 清除画布
canvas.drawColor(Color.WHITE);
// 获取尺寸
final Rect bounds = getBounds();
// 计算半径
final int radius = (Math.min(bounds.width(),bounds.height()) - mRingWidth) / 2;
// 计算矩形位置.
final int offsetX = (bounds.width() - radius * 2)/2 ;
final int offsetY = (bounds.height() - radius * 2)/2 ;
RectF rect = new RectF(offsetX,offsetY,offsetX + radius * 2,offsetY + radius *2);
// 1. 绘制圆环
final int centerX = bounds.width() / 2;
final int centerY = bounds.height() / 2;
final float outRingRadius = radius + mRingWidth / 2;
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(1);
canvas.drawCircle(centerX,centerY,outRingRadius,mPaint);
// 计算角度.
int angle = (int) ((mCurProgress * 1.0 / mMaxProgress) * 360);
// 2. 绘制进度圆环.
mPaint.setStrokeWidth(mRingWidth);
canvas.drawArc(rect,mStartAngle,angle,false,mPaint);
// 3. 绘制内圆
final float innerMaxCircleRadius = radius - mRingWidth / 2 + 1;
final float innerCurCircleRadius = (int) (innerMaxCircleRadius * (mCurProgress * 1.0 / mMaxProgress));
mPaint.setStyle(Paint.Style.FILL);
canvas.drawCircle(centerX,centerY,Math.abs(innerCurCircleRadius),mPaint);
}
@Override
public void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
mPaint.setColorFilter(colorFilter);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSPARENT;
}
@Override
public int getIntrinsicHeight() {
return getBounds().height();
}
@Override
public int getIntrinsicWidth() {
return getBounds().width();
}
}
自定义Drawable实现环形进度条.
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 在ReactNative使用过程中,我们使用最多的是通过fetch的方法来访问网络。但是当用于下载的时候,好像没有...
- 参考地址 http://sumile.cn/archives/1523.html attrs.xml
- 在日常iOS开发中,系统提供的控件常常无法满足业务功能,这个时候需要我们实现一些自定义控件。自定义控件能让我们完全...