最近有看到一个自定义等分圆的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. Android中的动画,选择器,样式和主题的使用

    一.动画: 1.动画的分类: 1).Tween动画:这种实现方式可以使视图组件移动.放大.缩小以及产生透明度的变化: 2).Frame动画:传统的动画方法,通过顺序的播放排列好的图片来实现,类似电影. ...

  2. tableview随笔

    //获得row NSInteger row = [[self.treeTableViewindexPathForCell:(UITableViewCell *)[[[notification.user ...

  3. 【Thinkphp5】封装layer弹窗方法

    1 官网下载layer 2 引入文件: <!--layer,官网可下载--> <script type="text/javascript" src="/ ...

  4. javascript关于链接的一些用法

    (1)javascript:openURL() http://www.kpdown.com/search?name=Ben Nadel 此URL后边有一个name参数,只不过参数的值竟然带了空格,这样 ...

  5. call和apply方法

    /* * @ call和apply方法 * @ 当一个object没有某个方法,但是其他的有,我们可以借助call或apply用其它对象的方法来操作. * @ (有方法的)对象.call(" ...

  6. Array.prototype.forEach数组遍历

    forEach是Array新方法中最基本的一个,就是遍历,循环.先看以前是怎么遍历数组的 常用遍历 var arr = [1,2,3,4,5]; for(var i = 0; i < arr.l ...

  7. LCA(离线算法)

    hdu4547 CD操作 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) To ...

  8. 网络费用流-最小k路径覆盖

    多校联赛第一场(hdu4862) Jump Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  9. python下几种打开文件的方式

    昨天看完了这本python进阶,感觉这本书对我启发很大,做了三张纸的笔记,方便我在遇到问题的时候翻阅,然后寻找可能的解决方案.作为一个使用Python一年的小白,虽然说不是小白,但是这一年来基本上是用 ...

  10. 170515、mybatis批量操作

    //Java代码 public void batchAdd(){ SqlSession sqlSession = SqlSessionFactoryUtil.getSqlSession(); Stud ...