如图:
自定义属性,在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:android="http://schemas.android.com/apk/res/android" 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:id="@+id/superview" 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:id="@+id/tv" 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