如图:
自定义属性,在values文件夹下创建 attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="SuperCircleView">
<!-- 圆的半径 -->
<attr name="min_circle_radio" format="integer"/>
<!-- 圆环的宽度 -->
<attr name="ring_width" format="float"/>
<!-- 内圆的颜色 -->
<attr name="circle_color" format="color"/>
<!-- 外圆的颜色 -->
<attr name="max_circle_color" format="color"/>
<!-- 圆环的默认颜色 -->
<attr name="ring_normal_color" format="color"/>
<!-- 圆环要显示的彩色的区域(随着数值的改变,显示不同大小的彩色区域)-->
<attr name="ring_color_select" format="integer"/>
<!-- 绘制内容的数值 -->
<attr name="maxValue" format="integer" />
<attr name="value" format="integer" />
</declare-styleable>
</resources>
自定义view
package com.chuanye.huanxingtu;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.SweepGradient;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
public class SuperCircleView extends View {
private final String TAG = "SuperCircleView";
private ValueAnimator valueAnimator;
private int mViewCenterX; //view宽的中心点(可以暂时理解为圆心)
private int mViewCenterY; //view高的中心点(可以暂时理解为圆心)
private int mMinRadio; //最里面白色圆的半径
private float mRingWidth; //圆环的宽度
private int mMinCircleColor; //最里面圆的颜色
private int mRingNormalColor; //默认圆环的颜色
private Paint mPaint;
private int color[] = new int[3]; //渐变颜色
private RectF mRectF; //圆环的矩形区域
private int mSelectRing = 0; //要显示的彩色区域(岁数值变化)
private int mMaxValue;
public SuperCircleView(Context context) {
super(context);
Log.i(TAG,"SuperCircleView--->1SuperCircleView");
}
public SuperCircleView(Context context, AttributeSet attrs) {
super(context, attrs);
Log.i(TAG,"SuperCircleView--->2SuperCircleView");
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SuperCircleView);
//最里面白色圆的半径
mMinRadio = a.getInteger(R.styleable.SuperCircleView_min_circle_radio, 300);
//圆环宽度
mRingWidth = a.getFloat(R.styleable.SuperCircleView_ring_width, 40);
//最里面的圆的颜色(绿色)
mMinCircleColor = a.getColor(R.styleable.SuperCircleView_circle_color, context.getResources().getColor(R.color.green));
// mMinCircleColor = a.getColor(R.styleable.SuperCircleView_circle_color, context.getResources().getColor(R.color.green));
//圆环的默认颜色(圆环占据的是里面的圆的空间)
mRingNormalColor = a.getColor(R.styleable.SuperCircleView_ring_normal_color, context.getResources().getColor(R.color.gray));
//圆环要显示的彩色的区域
mSelectRing = a.getInt(R.styleable.SuperCircleView_ring_color_select, 0);
mMaxValue = a.getInt(R.styleable.SuperCircleView_maxValue, 100);
a.recycle();
//抗锯齿画笔
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
//防止边缘锯齿
mPaint.setAntiAlias(true);
//需要重写onDraw就得调用此
this.setWillNotDraw(false);
//圆环渐变的颜色
color[0] = Color.parseColor("#FFD300");
color[1] = Color.parseColor("#FF0084");
color[2] = Color.parseColor("#16FF00");
}
public SuperCircleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
Log.i(TAG,"SuperCircleView--->3SuperCircleView");
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
Log.i(TAG,"SuperCircleView--->onLayout");
//view的宽和高,相对于父布局(用于确定圆心)
int viewWidth = getMeasuredWidth();
int viewHeight = getMeasuredHeight();
mViewCenterX = viewWidth / 2;
mViewCenterY = viewHeight / 2;
//画矩形
mRectF = new RectF(mViewCenterX - mMinRadio - mRingWidth / 2, mViewCenterY - mMinRadio - mRingWidth / 2, mViewCenterX + mMinRadio + mRingWidth / 2, mViewCenterY + mMinRadio + mRingWidth / 2);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Log.i(TAG,"SuperCircleView--->onDraw");
mPaint.setColor(mMinCircleColor);
canvas.drawCircle(mViewCenterX, mViewCenterY, mMinRadio, mPaint);
//画默认圆环
drawNormalRing(canvas);
//画彩色圆环
drawColorRing(canvas);
}
/**
* 画默认圆环
*
* @param canvas
*/
private void drawNormalRing(Canvas canvas) {
Paint ringNormalPaint = new Paint(mPaint);
ringNormalPaint.setStyle(Paint.Style.STROKE);
ringNormalPaint.setStrokeWidth(mRingWidth);
ringNormalPaint.setColor(mRingNormalColor);//圆环默认颜色为灰色
canvas.drawArc(mRectF, 360, 360, false, ringNormalPaint);
}
/**
* 画彩色圆环
*
* @param canvas
*/
private void drawColorRing(Canvas canvas) {
Paint ringColorPaint = new Paint(mPaint);
ringColorPaint.setStyle(Paint.Style.STROKE);
ringColorPaint.setStrokeWidth(mRingWidth);
ringColorPaint.setShader(new SweepGradient(mViewCenterX, mViewCenterX, color, null));
//逆时针旋转90度
canvas.rotate(-90, mViewCenterX, mViewCenterY);
canvas.drawArc(mRectF, 360, mSelectRing, false, ringColorPaint);
ringColorPaint.setShader(null);
}
//***************************************用于更新圆环表示的数值*****************************************************
/**
* 设置当前值
*
* @param value
*/
public void setValue(int value, TextView textView) {
if (value > mMaxValue) {
value = mMaxValue;
}
int start = 0;
int end = value;
startAnimator(start, end, 2000,textView);
}
private void startAnimator(int start, int end, long animTime, final TextView textView) {
valueAnimator = ValueAnimator.ofInt(start, end);
valueAnimator.setDuration(animTime);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Log.i(TAG, "onAnimationUpdate: animation.getAnimatedValue()::"+animation.getAnimatedValue());
int i = Integer.valueOf(String.valueOf(animation.getAnimatedValue()));
textView.setText(i + "");
//每个单位长度占多少度
mSelectRing=(int) (360 * (i / 100f));
Log.i(TAG, "onAnimationUpdate: mSelectRing::"+mSelectRing);
invalidate();
}
});
valueAnimator.start();
}
}
布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:andro
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:gravity="center"
tools:context=".Main1Activity">
<FrameLayout
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_gravity="center">
<com.chuanye.huanxingtu.SuperCircleView
android:
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:maxValue="100"
app:value="20"
app:ring_width="60" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="60dp"
android:text="信息完成度"
android:textColor="#CFD5DE"
android:textSize="18sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<TextView
android:
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textColor="#506946"
android:textSize="80sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="%"
android:textSize="28sp" />
</LinearLayout>
</FrameLayout>
</LinearLayout>
MainActivity中
package com.chuanye.huanxingtu;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import java.util.Random;
public class Main1Activity extends AppCompatActivity {
private static final String TAG = "Main1Activity";
SuperCircleView mSuperCircleView;
TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main1);
textView = findViewById(R.id.tv);
mSuperCircleView = findViewById(R.id.superview);
mSuperCircleView.setValue(100, textView);
mSuperCircleView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//随机设定圆环大小
int i = new Random().nextInt(100) + 1;
Log.i(TAG, "onClick: i::" + i);
mSuperCircleView.setValue(i, textView);
}
});
}
}
完成
参考于://https://blog.csdn.net/zhangqunshuai/article/details/80733982