Android中自定义环形图2

如图:

自定义属性,在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

原文地址:https://www.cnblogs.com/changyiqiang/p/10893305.html