如图:

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

Android中自定义环形图2的更多相关文章

  1. Android中自定义环形图

    如图: 自定义view package com.riverlet.ringview; import android.animation.ObjectAnimator; import android.c ...

  2. [转]Android中自定义checkbox样式

    android中自定义checkbox的图片和大小   其实很简单,分三步: 1.在drawable中创建文件checkbox_selector.xml: <?xml version=" ...

  3. 转--Android中自定义字体的实现方法

    1.Android系统默认支持三种字体,分别为:“sans”, “serif”, “monospace 2.在Android中可以引入其他字体 . 复制代码 代码如下: <?xml versio ...

  4. Android中自定义ActionBar的背景色等样式style

    Android中想要去自定义ActionBar的背景色等样式. [折腾过程] 1.自己找代码,发现对应的配置的地方了: AndroidManifest.xml ? 1 2 <applicatio ...

  5. Android中自定义veiw使用Java中的回调方法

    //------------------MainActivity----中---------------------------------- import android.os.Bundle;imp ...

  6. android开发:Android 中自定义View的应用

    大家好我们今天的教程是在Android 教程中自定义View 的学习,对于初学着来说,他们习惯了Android 传统的页面布局方式,如下代码: <?xml version="1.0&q ...

  7. Android中自定义组合控件

    Android中自定义控件的情况非常多,一般自定义控件可以分为两种:继承控件及组合控件.前者是通过继承View或其子类,重写方法实现自定义的显示及事件处理方式:后者是通过组合已有的控件,来实现结构的简 ...

  8. Android中自定义ListView实现上拉加载更多和下拉刷新

    ListView是Android中一个功能强大而且很常用的控件,在很多App中都有ListView的下拉刷新数据和上拉加载更多这个功能.这里我就简单记录一下实现过程. 实现这个功能的方法不止一个,Gi ...

  9. Android中自定义View和自定义动画

    Android FrameWork 层给我们提供了很多界面组件,但是在实际的商业开发中这些组件往往并不能完全满足我们的需求,这时候我们就需要自定义我们自己的视图和动画. 我们要重写系统的View就必须 ...

随机推荐

  1. USACO Poker Hands

    洛谷 P3078 [USACO13MAR]扑克牌型Poker Hands 题目传送门 JDOJ 2359: USACO 2013 Mar Silver 1.Poker Hands JDOJ传送门 题目 ...

  2. freeradius client 和jradius安装编译

    freeradius client radtest只是用来调试的,radclient功能更强大.用法如下: From the man page we can see that radclient gi ...

  3. PATA1012The Best Rank(25分)

    To evaluate the performance of our first year CS majored students, we consider their grades of three ...

  4. 使用docker部署nginx+tomcat架构

    架构说明: 使用nginx+tomcat实现动态/静态(资源请求)分离和负载均衡. 参考文档: https://www.runoob.com/docker/docker-tutorial.html 配 ...

  5. 每日一问:讲讲 JVM 的类加载机制

    前面给大家讲解了 Java 虚拟的内存结构 以及 Java 虚拟机的垃圾回收机制,我们更加明白了 Java 的内存管理机制,今天我们来讲讲 Java 虚拟机的另外一个高频考点:类加载机制. JVM 的 ...

  6. java并发编程(九)ThreadLocal & InheritableThreadLocal

    参考文档: https://blog.csdn.net/u012834750/article/details/71646700 threadlocal内存泄漏:http://www.importnew ...

  7. win10 下安装 ZooKeeper 的方法

    ZooKeeper 下载地址: https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/ 1 随便解压到一个目录 2 在 zookeeper-3.x ...

  8. Jumpserver 5.2版本安装与部署

    组件说明 Jumpserver 为管理后台, 管理员可以通过 Web 页面进行资产管理.用户管理.资产授权等操作, 用户可以通过 Web 页面进行资产登录, 文件管理等操作 koko 为 SSH Se ...

  9. 016 Vuetify框架

    1.Vuetify优点 官方网站:https://vuetifyjs.com/zh-Hans/ 原因如下: Vuetify几乎不需要任何CSS代码,而element-ui许多布局样式需要我们来编写 V ...

  10. Nginx配置REWRITE隐藏index.php

    server { listen 80; server_name localhost; root D:\workspace\PHP\Atromic; location / { index index.p ...