package com.loaderman.customviewdemo;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View; import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List; /**
* Created by MQ on 2016/12/15.
*/ public class CakeView extends View {
//装载的饼状圆数据
private List<CakeBean> beanList;
//画圆的矩形
private RectF mRectF;
//右边的小矩形
private RectF iRectF;
private Paint mPaint;
private int mRWidth, mRHeight;
private float rotateDegree;//每个圆弧的起始角度
private float sumValue = 0;//所有值的和
private float diameter;//圆的直径
private float textY;//绘制文字的Y坐标 private float mRectHeight = 40;//矩形高度
private float mRectWidth = 80;//矩形宽度
private float mMargin = 40;//矩形和圆的距离
private Context mContext; public CakeView(Context context) {
//CakeView cakeView=new CakeView(context);
// 在代码中new CakeView()会调用这个构造函数
this(context, null);
} public CakeView(Context context, AttributeSet attrs) {
//InflateLayoutManager时会调用这个构造函数
this(context, attrs, 0);
} public CakeView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
init();
} private void init() {
beanList = new ArrayList<>();
mRectF = new RectF();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
} @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//MeasureSpec封装了父View传递给子View的布局要求
int wMode = MeasureSpec.getMode(widthMeasureSpec);
int wSize = MeasureSpec.getSize(widthMeasureSpec);
int hMode = MeasureSpec.getMode(heightMeasureSpec);
int hSize = MeasureSpec.getSize(heightMeasureSpec);
switch (wMode) {
case MeasureSpec.EXACTLY:
//相当于match_parent或者一个具体值
mRWidth = wSize;
break;
case MeasureSpec.AT_MOST:
// 相当于wrap_content 默认会充满父View
// 可以根据子View的大小来计算父View大小,这里先写死大小
mRWidth = (int) DpUtil.dp2px(mContext, 400f);
break;
case MeasureSpec.UNSPECIFIED:
//很少会用到
break;
default:
break;
}
switch (hMode) {
case MeasureSpec.EXACTLY:
//相当于match_parent或者一个具体值
mRHeight = hSize;
break;
case MeasureSpec.AT_MOST:
// 相当于wrap_content 默认会充满父View
// 可以根据子View的大小来计算父View大小,这里先写死大小
mRHeight = (int) DpUtil.dp2px(mContext, 200f);
break;
case MeasureSpec.UNSPECIFIED:
//很少会用到
break;
default:
break;
}
//存储测量好的宽和高
setMeasuredDimension(wSize, hSize);
} @Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
diameter = Math.min(mRWidth, mRHeight);
} @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
textY = 0f;
//设置圆形绘制的范围
mRectF.set(0, 0, diameter, diameter);
//画布中心X坐标向右移动(控件宽度-圆直径)之差的八分之一的距离
//画布中心Y坐标向下移动(控件宽度-圆直径)之差的二分之一的距离
canvas.translate((mRWidth - diameter) / 8, (mRHeight - diameter) / 2);
if (beanList.size() > 0 && Float.compare(sumValue, 0.0f) != 0) {
for (int i = 0; i < beanList.size(); i++) {
CakeBean bean = beanList.get(i);
//画圆弧
mPaint.setColor(bean.mColor);
canvas.drawArc(mRectF, rotateDegree, bean.degree, true, mPaint);
rotateDegree += bean.degree;
//画矩形和文字
drawRectAndText(canvas, bean);
}
}
} private void drawRectAndText(Canvas canvas, CakeBean bean) {
iRectF = new RectF();
//设置画矩形的范围
float left = diameter + mMargin;
float right = diameter + mMargin + mRectWidth;
float bottom = textY + mRectHeight;
iRectF.set(left, textY, right, bottom);
canvas.drawRect(iRectF, mPaint);
//设置颜色
mPaint.setColor(Color.BLACK);
//设置文字大小
mPaint.setTextSize(30);
//画文字
canvas.drawText(bean.name + "(" + new DecimalFormat(".00").format(bean.value / sumValue * 100) + "%)", right + 10, textY + 30, mPaint);
textY += mRectHeight;
} /**
* 饼状图添加数据
*
* @param beans CakeBean数据
*/
public void setData(List<CakeBean> beans) {
if (beans == null || beans.size() <= 0) return;
for (int i = 0; i < beans.size(); i++) {
CakeBean bean = beans.get(i);
sumValue += bean.value;
}
for (int i = 0; i < beans.size(); i++) {
CakeBean bean = beans.get(i);
bean.degree = bean.value / sumValue * 360;
beanList.add(bean);
}
invalidate();
} /**
* @param startDegree 设置起始角度
*/
public void setStartDegree(float startDegree) {
this.rotateDegree = startDegree;
invalidate();
}
}
package com.loaderman.customviewdemo;

import java.io.Serializable;

public class CakeBean implements Serializable {
public String name;//名字
public float value;//值
public float degree;//旋转过的角度
public int mColor;//圆弧颜色
}
package com.loaderman.customviewdemo;

import android.app.Activity;
import android.content.Context;
import android.util.DisplayMetrics; /**
* Created by MQ on 2016/12/16.
*/ public class DpUtil {
/**
* dp转换成px
*
* @param context Context
* @param dp dp
* @return px值
*/
public static float dp2px(Context context, float dp) {
final float scale = context.getResources().getDisplayMetrics().density;
return dp * scale + 0.5f;
} /**
* sp转换成px
*
* @param context Context
* @param sp sp
* @return px值
*/
public static float sp2px(Context context, float sp) {
final float scale = context.getResources().getDisplayMetrics().scaledDensity;
return sp * scale;
} /**
* 获得屏幕宽度
*
* @param context Context
* @return 屏幕宽度(像素)
*/
public static int getScreenSizeWidth(Context context) {
DisplayMetrics metric = new DisplayMetrics();
((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(metric);
return metric.widthPixels;
}
}
package com.loaderman.customviewdemo;

import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity; import java.util.ArrayList;
import java.util.List; public class MainActivity extends AppCompatActivity {
private List<CakeBean> beans;
private String[] names = {"php", "object-c", "c", "c++", "java", "android", "linux"};
private float[] values = {2f, 2f, 3f, 4f, 5f, 6f, 7f};
private int[] colArrs = {Color.RED, Color.parseColor("#4ebcd3"), Color.MAGENTA, Color.YELLOW, Color.GREEN, Color.parseColor("#f68b2b"), Color.parseColor("#6fb30d")};//圆弧颜色
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CakeView cake_view = (CakeView) findViewById(R.id.cake_view);
initData();
cake_view.setData(beans); } private void initData() {
beans = new ArrayList<>();
for (int i = 0; i < 7; i++) {
CakeBean bean = new CakeBean();
bean.name = names[i];
bean.value = values[i];
bean.mColor = colArrs[i];
beans.add(bean);
}
} }

效果图:

自定义View饼状图的绘制的更多相关文章

  1. 基于SpringMVC框架使用ECharts3.0实现折线图,柱状图,饼状图,的绘制(上篇)

    页面部分 <%@ page language="java" pageEncoding="UTF-8"%> <!DOCTYPE html> ...

  2. matplotlib学习日记(五)-各种饼状图的绘制

    (一)分裂式饼状图 import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np mpl.rcParams[& ...

  3. Android中饼状图的绘制

    https://blog.csdn.net/cen_yuan/article/details/52204281

  4. Android 自定义饼状图

    github 地址:https://github.com/dkest/PieView 简单分析 其实根据我们上面的知识已经能自己制作一个饼状图了.不过制作东西最重要的不是制作结果,而是制作思路. 相信 ...

  5. 【 D3.js 进阶系列 — 6.2 】 饼状图的拖拽

    本文讲解稍微复杂一些的拖拽应用,即拖拽饼图的各部分. 在[入门 - 第 9.1 章]讲解了如何制作饼状图.饼状图的各部分是用具有宽度的弧线来表示的.在与用户进行交互的时候,如果每一部分都能拖拽,是很有 ...

  6. 第三方Charts绘制图表四种形式:饼状图,雷达图,柱状图,直线图

    对于第三方框架Charts(Swift版本,在OC项目中需要添加桥接头文件),首先要解决在项目中集成的问题,集成步骤: 一.下载Charts框架 下载地址:https://github.com/dan ...

  7. DevExpress使用之ChartControl控件绘制图表(多坐标折线图、柱状图、饼状图)

    最近因为公司项目需要用到WinForm的DecExpress控件,在这里把一些使用方法总结一下. DevExpress中有一个专门用来绘制图表的插件ChartControl,可以绘制折线图.饼状图.柱 ...

  8. iOS:使用贝塞尔曲线绘制图表(折线图、柱状图、饼状图)

    1.介绍: UIBezierPath :画贝塞尔曲线的path类 UIBezierPath定义 : 贝赛尔曲线的每一个顶点都有两个控制点,用于控制在该顶点两侧的曲线的弧度. 曲线的定义有四个点:起始点 ...

  9. C#绘制立体三维饼状图

    转载自原文 C#绘制立体三维饼状图(超酷) 内容原文地址:LINK [翻译]Julijan Sribar著3D Pie Chart一个用于绘制立体三维饼状图的C#类库[简介]本文的想法就是创建一个独立 ...

随机推荐

  1. Delphi 指针类型

  2. python、第三篇:表相关操作

    一 存储引擎介绍 存储引擎即表类型,mysql根据不同的表类型会有不同的处理机制 详见:https://www.cnblogs.com/Forever-x/p/11317479.html 二 表介绍 ...

  3. deep_learning_Function_tf.add()、tf.subtract()、tf.multiply()、tf.div()

    tf.add().tf.subtract().tf.multiply().tf.div()函数介绍和示例 1. tf.add() 释义:加法操作 示例: x = tf.constant(2, dtyp ...

  4. select,poll.epoll区别于联系

    select,poll,epoll都是IO多路复用中的模型.再介绍他们特点时,先来看看多路复用的 模型. 同其他IO的不同的是,IO多路复用一次可以等多个文件描述符.大大提高了等待数据准备好的时间的效 ...

  5. PAT Basic 1017 A除以B (20 分)

    本题要求计算 /,其中 A 是不超过 1000 位的正整数,B 是 1 位正整数.你需要输出商数 Q 和余数 R,使得 A=B×Q+R 成立. 输入格式: 输入在一行中依次给出 A 和 B,中间以 1 ...

  6. lightinthebox头部分类菜单下拉导航,使鼠标移到See All Categories就显示下拉菜单

    lightinthebox头部分类菜单下拉导航,使鼠标移到See All Categories就显示下拉菜单 打开includes\templates\lightinthebox\common\tpl ...

  7. vs code 保存显示无法写入文件的解决方法

    右键文件夹点击属性 选择安全 把当前用户权限都勾选上就可以了

  8. Kubernetes 编排神器之 Helm

    什么是Kubernetes Helm?为什么要使用Helm? 前言 编写一堆Kubernetes配置文件是一件很麻烦的事情.对于一些容器,我们可能需要10多个yaml文件.维护它们是一个问题,而且在不 ...

  9. CentOS 7 安装 metasploit-framework

    1 一键安装metasploit-framework apt-get install curl,wgetcurl https://raw.githubusercontent.com/rapid7/me ...

  10. 红帽Linux故障定位技术详解与实例(2)

    红帽Linux故障定位技术详解与实例(2) 2011-09-28 14:26 圈儿 BEAREYES.COM 我要评论(0) 字号:T | T 在线故障定位就是在故障发生时, 故障所处的操作系统环境仍 ...