本文参考自https://www.jianshu.com/p/bc7bdaeb9eb2
思路:首先画一个最外面的圆,然后再画一可以旋转的弧形,最后画一中间的圆。
首先,在values中新建attrs.xml文件,文件中的内容为:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="BoxDrawingView">
<attr name="ringWidth" format="dimension"/>
<attr name="startAngle" format="integer"/>
<attr name="endAngle" format="integer"/>
<attr name="duation" format="integer"/>
<attr name="bottomColor" format="color"/>
<attr name="topColor" format="color"/>
<attr name="centerColor" format="color"/>
<attr name="textColor" format="color"/>
</declare-styleable>
</resources>
此步骤和CircularView中的
//TODO需要从attrs中获取参数
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.BoxDrawingView);
setBottomColor(a.getColor(R.styleable.BoxDrawingView_bottomColor, bottomColor));
setTopColor(a.getColor(R.styleable.BoxDrawingView_topColor, topColor));
setCenterColor(a.getColor(R.styleable.BoxDrawingView_centerColor, centerColor));
setEndAngle(a.getInteger(R.styleable.BoxDrawingView_endAngle, endAngle));
setStartAngle(a.getInteger(R.styleable.BoxDrawingView_startAngle, startAngle));
setDuation(a.getInteger(R.styleable.BoxDrawingView_duation, duation));
setRingWidth(a.getDimensionPixelOffset(R.styleable.BoxDrawingView_ringWidth, ringWidth));
a.recycle();
相对照,为定义自定义view的属性,和android:layout_width="100dp"
;相类似
public class CircularView extends View {
//底色的圆:最大圆
private float bottomWidth = 200;
private Paint bottomPaint;
private int bottomColor = Color.GRAY;//底圆的颜色
//上层的扇形
private float topWidth;
private Paint topPaint;
private int topColor = Color.DKGRAY;//代表进度的扇形的颜色
private int ringWidth = 20;//环形的宽度
private int endAngle = 0;//上层圆环的着色,目标角度
private int currentAngle = 0;//上层圆环的着色,当前角度
private int startAngle = 180;//上层圆环的着色,开始角度
//中间圆
private int centerColor = Color.WHITE;//圆环中间的颜色
private Paint centerPaint;
boolean isFirst = true;
boolean isDrawText = true;
private int duation = 2000;//动画的事件长度
public CircularView(Context context) {
super(context);
}
public CircularView(Context context, AttributeSet attrs) {
super(context, attrs);
//初始化画笔
topPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
bottomPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
centerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
//TODO需要从attrs中获取参数
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.BoxDrawingView);
setBottomColor(a.getColor(R.styleable.BoxDrawingView_bottomColor, bottomColor));
setTopColor(a.getColor(R.styleable.BoxDrawingView_topColor, topColor));
setCenterColor(a.getColor(R.styleable.BoxDrawingView_centerColor, centerColor));
setEndAngle(a.getInteger(R.styleable.BoxDrawingView_endAngle, endAngle));
setStartAngle(a.getInteger(R.styleable.BoxDrawingView_startAngle, startAngle));
setDuation(a.getInteger(R.styleable.BoxDrawingView_duation, duation));
setRingWidth(a.getDimensionPixelOffset(R.styleable.BoxDrawingView_ringWidth, ringWidth));
a.recycle();
}
@Override
protected void onDraw(Canvas canvas) {
if (isFirst) {
isFirst = false;
topWidth = getWidth();
bottomWidth = getWidth();
drawBottom(canvas);
drawTop(canvas);
drawCenter(canvas);
startAnimation();
} else {
drawBottom(canvas);
drawTop(canvas);
drawCenter(canvas);
}
}
protected void drawBottom(Canvas canvas) {
//画底部的圆
bottomPaint.setColor(bottomColor);
canvas.drawCircle(getWidth() / 2, getHeight() / 2, bottomWidth / 2, bottomPaint);
}
protected void drawTop(Canvas canvas) {
//画出中间的着色扇形
topPaint.setColor(topColor);
RectF rectF = new RectF(0, 0, getWidth(), getWidth());
canvas.drawArc(rectF, startAngle, currentAngle, true, topPaint);
}
protected void drawCenter(Canvas canvas) {
//画出最中间的圆
centerPaint.setColor(centerColor);
canvas.drawCircle(getWidth() / 2, getHeight() / 2, (topWidth - ringWidth * 2) / 2, centerPaint);
}
private void startAnimation() {
ValueAnimator animator = ValueAnimator.ofInt(0, endAngle);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
currentAngle = (int) animation.getAnimatedValue();
invalidate();
}
});
animator.setDuration(duation);
animator.start();
}
//设置最终扇形的角度
public void setEndAngle(int angle) {
this.endAngle = angle;
}
//设置开始的角度
public void setStartAngle(int startAngle) {
this.startAngle = startAngle;
}
//设置动画时常
public void setDuation(int duation) {
this.duation = duation;
}
//设置圆环的宽度
public void setRingWidth(int ringWidth) {
this.ringWidth = ringWidth;
}
//设置进度条的颜色
public void setTopColor(int topColor) {
this.topColor = topColor;
}
//设置中间小圆的颜色
public void setCenterColor(int centerColor) {
this.centerColor = centerColor;
}
//设置底圆的颜色
public void setBottomColor(int bottomColor) {
this.bottomColor = bottomColor;
}
//刷新View
public void refresh() {
startAnimation();
}
}
使用
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_alignParentEnd="true"
android:layout_margin="16sp">
<com.bignerdranch.android.fardimension.view.CircularView
android:id="@+id/marking_view"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
app:bottomColor="#fffae3"
app:ringWidth="8dp"
app:topColor="#58564c" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="10dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textColor="#506946"
android:textSize="32sp" />
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:text="分数"
android:textColor="#CFD5DE"
android:textSize="16sp" />
</FrameLayout>
在activity中的使用,其中score可以替换为0-100中的任意数字
//设置环形进度条的参数
circularView.setEndAngle((int) (360 * (score / 100f)));
circularView.setStartAngle(270);
circularView.setDuation(2000);
circularView.refresh();
网友评论