最近有看到一个自定义等分圆的View,自己尝试做了一个类似的,效果图如下图(1)所示:

图(1)

  实现方法:自定义View-ColorCircle,需要的知道的值有圆的半径,等分个数以及扇形颜色。

    /**
* 定义几种颜色
*/
private static int COLOR[] = {Color.RED, Color.BLUE, Color.GREEN, Color.YELLOW, Color.BLACK};
/**
* 圆等分默认数目
*/
private static int DIV_SIZE = 3; private Paint mPaint;
  /**
   * 圆默认半径
   */
private static final int DEFAULT_RADIUS = 200;
private int mRadius = DEFAULT_RADIUS;
public ColorCircle(Context context) {
this(context, null);
} public ColorCircle(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
} public ColorCircle(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mPaint = new Paint();
mPaint.setStyle(Paint.Style.FILL);
}

  在onMeasure中我们需要根据widthMeasureSpec & heightMeasureSpec重新计算ColorCircle View的尺寸以及圆的半径(因为默认圆的直径可能会大于View的高 or 宽)。

    @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec); int width;
int height; if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else {
width = mRadius * 2 + getPaddingLeft() + getPaddingRight();
if (widthMode == MeasureSpec.AT_MOST) {
width = Math.min(width, widthSize);
}
} if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else {
height = mRadius * 2 + getPaddingTop() + getPaddingBottom();
if (heightMode == MeasureSpec.AT_MOST) {
height = Math.min(width, heightSize);
}
} setMeasuredDimension(width, height);
mRadius = (int) (Math.min(width - getPaddingLeft() - getPaddingRight(),
height - getPaddingTop() - getPaddingBottom()) * 1.0f / 2);
}

  最后在onDraw里通过canvas.drawArc()来绘制扇形。

    @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//平移Canvas到屏幕中心,之后的绘制以中心点为初始点
canvas.translate((getWidth() + getPaddingLeft() - getPaddingRight()) / 2,
             (getHeight() + getPaddingTop() - getPaddingBottom()) / 2);
//定义一个RectF对象,表示扇形绘制区域
RectF oval = new RectF(-mRadius, -mRadius, mRadius, mRadius);
float firstAngle = 0.0f;
float divideAngle = (360 * 1.0f) / DIV_SIZE;//根据DIV_SIZE来算每个扇形的角度
for (int i=0; i<DIV_SIZE; i++) {
mPaint.setColor(COLOR[i]);
canvas.drawArc(oval, (firstAngle + i * divideAngle), divideAngle, true, mPaint);
}
}     public void setDivSize(int size){
        DIV_SIZE = size;
        invalidate();
    }     public int getDivSize(){
        DIV_SIZE = size;
    }
 

  最后还预留了一个setDivSize()接口,方便自定义ColorCircle View动态变化扇形数目。我这里是通过Seekbar来动态切换DIV_SIZE。

    mColorCircle = (ColorCircle)findViewById(R.id.color_circle);
mSeekBar = (SeekBar)findViewById(R.id.seek_bar);
mSeekBar.setMax(4);//因为颜色数目原因,这里seekBar的最大值设置为了4。
int pro = mColorCircle.getSize();
mSeekBar.setProgress(pro); mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mColorCircle.setDivSize(progress + 1);
} @Override
public void onStartTrackingTouch(SeekBar seekBar) {
} @Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});

  效果图如下:

 

Android 自定义View - 饼图的更多相关文章

  1. Android自定义View 画弧形,文字,并增加动画效果

    一个简单的Android自定义View的demo,画弧形,文字,开启一个多线程更新ui界面,在子线程更新ui是不允许的,但是View提供了方法,让我们来了解下吧. 1.封装一个抽象的View类   B ...

  2. (转)[原] Android 自定义View 密码框 例子

    遵从准则 暴露您view中所有影响可见外观的属性或者行为. 通过XML添加和设置样式 通过元素的属性来控制其外观和行为,支持和重要事件交流的事件监听器 详细步骤见:Android 自定义View步骤 ...

  3. Android 自定义View合集

    自定义控件学习 https://github.com/GcsSloop/AndroidNote/tree/master/CustomView 小良自定义控件合集 https://github.com/ ...

  4. Android 自定义View (五)——实践

    前言: 前面已经介绍了<Android 自定义 view(四)-- onMeasure 方法理解>,那么这次我们就来小实践下吧 任务: 公司现有两个任务需要我完成 (1)监测液化天然气液压 ...

  5. Android 自定义 view(四)—— onMeasure 方法理解

    前言: 前面我们已经学过<Android 自定义 view(三)-- onDraw 方法理解>,那么接下我们还需要继续去理解自定义view里面的onMeasure 方法 推荐文章: htt ...

  6. Android 自定义 view(三)—— onDraw 方法理解

    前言: 上一篇已经介绍了用自己定义的属性怎么简单定义一个view<Android 自定义view(二) -- attr 使用>,那么接下来我们继续深究自定义view,下一步将要去简单理解自 ...

  7. Android 自定义view(二) —— attr 使用

    前言: attr 在前一篇文章<Android 自定义view -- attr理解>已经简单的进行了介绍和创建,那么这篇文章就来一步步说说attr的简单使用吧 自定义view简单实现步骤 ...

  8. Android 自定义View

    Android 自定义View流程中的几个方法解析: onFinishInflate():从布局文件.xml加载完组件后回调 onMeasure() :调用该方法负责测量组件大小 onSizeChan ...

  9. Android自定义View之CircleView

    Android自定义View之CircleView 版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请表明出处:http://www.cnblogs.com/cavalier-/p/5999 ...

随机推荐

  1. 查看网卡流量:nload

    nload命令用于查看网卡流量,用法如下: [root@localhost ~]$ yum install -y epel-release [root@localhost ~]$ yum instal ...

  2. Unity随机Prefab,自动前往某点处理

    对与U3D  AI,看了下,自己做了小功能,以备后用啊! 一,在某区域随机产生某个对象 C# 文件名称为RadomAPoint.cs using UnityEngine; using System.C ...

  3. Extjs6.2.0搭建项目框架

    1.安装 首先你总要去官网下载ext-6.2.0-gpl.zip和安装Sencha CMD工具来管理ExtJs项目,ext-6.2.0-gpl.zip下载完成解压先放在一边,一会用到. Sencha ...

  4. IOS实例方法和类方法的区别

    类方法和实例方法   实例方法是— 类开头是+ 实例方法是用实例对象访问,类方法的对象是类而不是实例,通常创建对象或者工具类. 在实例方法里,根据继承原理发送消息给self和super其实都是发送给s ...

  5. HDU 4462Scaring the Birds(枚举所有状态)

    Scaring the Birds Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  6. LeetCode——Sqrt(x)

    Description: Implement int sqrt(int x). Compute and return the square root of x. 好好学习数学还是非常有用的,牛顿迭代法 ...

  7. Android Log.isLoggable方法异常:exceeds limit of 23 characters

    AndroidRuntime: java.lang.IllegalArgumentException: Log tag "AccountSetupIncomingFragment" ...

  8. java如何使用base64生成图片文件

    import org.apache.commons.codec.binary.Base64; public static void decodeFile(String base64Str,File f ...

  9. ExecutorService的四种线程池

    转自:https://www.cnblogs.com/zhaoyan001/p/7049627.html 1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? new ...

  10. svn-maven-tomcat自动发布脚本

    #!/bin/sh #svn-maven-tomcat自动发布脚本 #变量设置 svnpath=svn://10.60.10.120/研发部/xx-maven svnusername=xxx svnp ...