Android自定义图表饼图View

import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.support.v4.content.LocalBroadcastManager;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

import com.axeac.android.sdk.R;
import com.axeac.android.sdk.adapters.OptionAdapter;
import com.axeac.android.sdk.dialog.CustomDialog;
import com.axeac.android.sdk.tools.StringUtil;
import com.axeac.android.sdk.utils.CommonUtil;
import com.axeac.android.sdk.utils.DensityUtil;
import com.axeac.android.sdk.utils.StaticObject;

public class Pie extends View {
    /**
     * 边距长度
     * */
    private static final int DEFAULT_PADDING_LENGTH = 25;
    /**
     * 默认半径
     * */
    private static final int DEFAULT_RADIUS_LENGTH = 200;

    private Activity ctx;
    /**
     * Point对象
     * */
    private Point centre = new Point(0, 0);
    /**
     * RectF对象
     * */
    private RectF rect;

    /**
     *圆半径
     */
    private int radius = DEFAULT_RADIUS_LENGTH;

    /**
     * 不同类型饼图标志
     * <br>可选值:1  2  1代表常规饼图,2代表空心饼图
     * */
    private int type;

    /**
     * 标题文本
     * */
    private String title;
    /**
     * 标题文字尺寸
     * */
    private String titleFont;
    /**
     * 子标题文本
     * */
    private String subTitle;
    /**
     * 子标题文字尺寸
     * */
    private String subTitleFont;
    /**
     * 数据文字尺寸
     * */
    private String dataTitleFont;
    /**
     * 中间标题文本
     * */
    private String titleCenter;
    /**
     * 中间标题文字尺寸
     * */
    private String titleCenterFont;

    /**
     * 百分比文字尺寸
     * */
    private String perFont;

    /**
     * 顶部标题文本
     * */
    private String titleTop;

    /**
     * 顶部标题文字尺寸
     * */
    private String titleTopFont;

    /**
     * 顶部副标题文本
     * */
    private String titleTopSub;
    /**
     * 顶部副标题文字尺寸
     * */
    private String titleTopSubFont;

    /**
     * 存储图形数据的Map集合
     * */
    private LinkedHashMap<String, String[]> datas;
    /**
     * 存放颜色值的list集合
     * */
    private ArrayList<Integer> colors;

    /**
     * 存储点击显示数据的list集合
     * */
    private ArrayList<String> itemClicks;

    /**
     * 点击时显示的文字
     * */
    private String click;


    private boolean isPerData = false;

    /**
     * 存储扇形角度的list集合
     * */
    private ArrayList<Integer[]> angles = new ArrayList<Integer[]>();

    public Pie(Activity ctx) {
        super(ctx);
        this.ctx = ctx;
        this.setLayoutParams(new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.MATCH_PARENT, 100));
        this.setBackgroundColor(getResources().getColor(R.color.background));
        this.getBackground().setAlpha(180);
    }

    /**
     * 设置饼图类型
     * @param type
     * 可选值:1、2(1代表常规饼图,2代表空心饼图)
     * */
    public void setType(int type){
        this.type = type;
    }

    /**
     * 设置标题文本
     * @param title
     * 标题文本
     * */
    public void setTitle(String title) {
        this.title = title;
    }

    /**
     * 设置标题文字尺寸
     * @param titleFont
     * 标题文字尺寸
     * */
    public void setTitleFont(String titleFont) {
        this.titleFont = titleFont;
    }

    /**
     * 设置子标题文本
     * @param subTitle
     * 子标题文本
     * */
    public void setSubTitle(String subTitle) {
        this.subTitle = subTitle;
    }

    /**
     * 设置子标题文字尺寸
     * @param subTitleFont
     * 子标题文字尺寸
     * */
    public void setSubTitleFont(String subTitleFont) {
        this.subTitleFont = subTitleFont;
    }

    /**
     * 设置数据文字尺寸
     * @param dataTitleFont
     * 数据文字尺寸
     * */
    public void setDataTitleFont(String dataTitleFont) {
        this.dataTitleFont = dataTitleFont;
    }

    /**
     * 设置中间标题文本
     * @param titleCenter
     * 中间标题文本
     * */
    public void setTitleCenter(String titleCenter) {
        this.titleCenter = titleCenter;
    }

    /**
     * 设置中间标题文字尺寸
     * @param titleCenterFont
     * 中间标题文字尺寸
     * */
    public void setTitleCenterFont(String titleCenterFont) {
        this.titleCenterFont = titleCenterFont;
    }

    /**
     * 设置百分比文字尺寸
     * @param perFont
     * 百分比文字尺寸
     * */
    public void setPerFont(String perFont) {
        this.perFont = perFont;
    }

    /**
     * 设置顶部标题文本
     * @param titleTop
     * 顶部标题文本
     * */
    public void setTitleTop(String titleTop) {
        this.titleTop = titleTop;
    }

    /**
     * 设置顶部标题文字尺寸
     * @param titleTopFont
     * 顶部标题文字尺寸
     * */
    public void setTitleTopFont(String titleTopFont) {
        this.titleTopFont = titleTopFont;
    }

    /**
     * 设置顶部副标题文本
     * @param titleTopSub
     * 顶部副标题文本
     * */
    public void setTitleTopSub(String titleTopSub) {
        this.titleTopSub = titleTopSub;
    }

    /**
     * 设置顶部副标题文字尺寸
     * @param titleTopSubFont
     * 顶部副标题文字尺寸
     * */
    public void setTitleTopSubFont(String titleTopSubFont) {
        this.titleTopSubFont = titleTopSubFont;
    }

    /**
     * 对datas进行赋值(图形数据集合)
     * @param datas
     * 图形数据集合
     * */
    public void setDatas(LinkedHashMap<String, String[]> datas) {
        this.datas = datas;
    }

    /**
     * 对colors进行赋值(颜色值集合)
     * @param colors
     * 颜色值集合
     * */
    public void setColor(ArrayList<Integer> colors) {
        this.colors = colors;
    }

    /**
     * 对itemClicks进行赋值(点击显示数据集合)
     * @param itemClicks
     * 点击时显示的数据的集合
     * */
    public void setItemClick(ArrayList<String> itemClicks) {
        this.itemClicks = itemClicks;
    }

    /**
     * 设置点击时显示的文字
     * @param click
     * 点击时显示的文字
     * */
    public void setClick(String click) {
        this.click = click;
    }

    /**
     * 对isPerData赋值
     * @param isPerData
     *
     * */
    public void setIsPerData(boolean isPerData) {
        this.isPerData = isPerData;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawChart(canvas);
    }

    /**
     * 绘制饼图以及标题等
     * @param canvas
     * Canvas对象
     * */
    private void drawChart(Canvas canvas) {
        radius = (int) (this.getWidth() * 0.618 / 2f) - DEFAULT_PADDING_LENGTH * 2;
        Rect topLeftRect = drawTitleTop(canvas);
        Rect topRightRect = drawDataTitle(canvas, topLeftRect);
        int titleTopHeight = topLeftRect.bottom;//> topRightRect.bottom ? topLeftRect.bottom : topRightRect.bottom;
        Rect bottomRect = drawTitleBottom(canvas, titleTopHeight);
        if (title.equals("") && subTitle.equals("")) {
            this.setLayoutParams(new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT, bottomRect.top + DEFAULT_PADDING_LENGTH));
        } else {
            this.setLayoutParams(new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT, bottomRect.bottom));
        }
        centre = new Point(DensityUtil.dip2px(ctx, 100) + (bottomRect.width() / 2), titleTopHeight + radius + DEFAULT_PADDING_LENGTH);

        if (type==1){
            rect = new RectF(centre.x - radius, centre.y - radius, centre.x + radius, centre.y + radius);
            drawBorderCircle(canvas);
            drawInsideBorderCircle(canvas);
            drawDiagram(canvas);
            drawSumCircle(canvas);
        }
        if (type==2) {
            rect = new RectF(centre.x - radius-10, centre.y - radius-10, centre.x + radius+10, centre.y + radius+10);
            drawDiagram(canvas);
            drawSumCircle(canvas);
            drawCenterCircle(canvas);
            drawInCircle(canvas);
        }

    }

    /**
     * 绘制顶部主副标题
     * @param canvas
     * Canvas对象
     */
    private Rect drawTitleTop(Canvas canvas) {
        // 主标题
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        float titleTopTextSize = 30;
        if (titleTopFont != null && !"".equals(titleTopFont)) {
            if (titleTopFont.indexOf(";") != -1) {
                String[] strs = titleTopFont.split(";");
                for (String str : strs) {
                    if (str.startsWith("font-size")) {
                        int index = str.indexOf(":");
                        if (index == -1)
                            continue;
                        String s = str.substring(index + 1).trim();
                        paint.setTextSize(Float.parseFloat(s.replace("px", "").trim()));
                        titleTopTextSize = Float.parseFloat(s.replace("px", "").trim());
                    } else if (str.startsWith("style")) {
                        int index = str.indexOf(":");
                        if (index == -1)
                            continue;
                        String s = str.substring(index + 1).trim();
                        if ("bold".equals(s)) {
                            paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
                        } else if ("italic".equals(s)) {
                            paint.setTypeface(Typeface.defaultFromStyle(Typeface.ITALIC));
                        } else {
                            if (s.indexOf(",") != -1) {
                                if ("bold".equals(s.split(",")[0]) && "italic".equals(s.split(",")[1])) {
                                    paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD_ITALIC));
                                }
                                if ("bold".equals(s.split(",")[1]) && "italic".equals(s.split(",")[0])) {
                                    paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD_ITALIC));
                                }
                            }
                        }
                    } else if (str.startsWith("color")) {
                        int index = str.indexOf(":");
                        if (index == -1)
                            continue;
                        String s = str.substring(index + 1).trim();
                        if (CommonUtil.validRGBColor(s)) {
                            int r = Integer.parseInt(s.substring(0, 3));
                            int g = Integer.parseInt(s.substring(3, 6));
                            int b = Integer.parseInt(s.substring(6, 9));
                            paint.setColor(Color.rgb(r, g, b));
                        } else {
                            paint.setColor(Color.BLACK);
                        }
                    }
                }
            }
        }
        paint.setStyle(Style.STROKE);
        canvas.drawText(titleTop, DEFAULT_PADDING_LENGTH, paint.getFontMetrics().bottom - paint.getFontMetrics().top, paint);
        int titleWidth = (int) paint.measureText(titleTop) + DEFAULT_PADDING_LENGTH * 2;
        int titleHeight = (int) (paint.getFontMetrics().bottom - paint.getFontMetrics().top + titleTopTextSize * 0.75);
        // 副标题
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        float titleTopSubTextSize = 23;
        if (titleTopSubFont != null && !"".equals(titleTopSubFont)) {
            if (titleTopSubFont.indexOf(";") != -1) {
                String[] strs = titleTopSubFont.split(";");
                for (String str : strs) {
                    if (str.startsWith("font-size")) {
                        int index = str.indexOf(":");
                        if (index == -1) continue;
                        String s = str.substring(index + 1).trim();
                        paint.setTextSize(Float.parseFloat(s.replace("px", "").trim()));
                        titleTopSubTextSize = Float.parseFloat(s.replace("px", "").trim());
                    } else if (str.startsWith("style")) {
                        int index = str.indexOf(":");
                        if (index == -1)
                            continue;
                        String s = str.substring(index + 1).trim();
                        if ("bold".equals(s)) {
                            paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
                        } else if ("italic".equals(s)) {
                            paint.setTypeface(Typeface.defaultFromStyle(Typeface.ITALIC));
                        } else {
                            if (s.indexOf(",") != -1) {
                                if ("bold".equals(s.split(",")[0]) && "italic".equals(s.split(",")[1])) {
                                    paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD_ITALIC));
                                }
                                if ("bold".equals(s.split(",")[1]) && "italic".equals(s.split(",")[0])) {
                                    paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD_ITALIC));
                                }
                            }
                        }
                    } else if (str.startsWith("color")) {
                        int index = str.indexOf(":");
                        if (index == -1)
                            continue;
                        String s = str.substring(index + 1).trim();
                        if (CommonUtil.validRGBColor(s)) {
                            int r = Integer.parseInt(s.substring(0, 3));
                            int g = Integer.parseInt(s.substring(3, 6));
                            int b = Integer.parseInt(s.substring(6, 9));
                            paint.setColor(Color.rgb(r, g, b));
                        } else {
                            paint.setColor(Color.BLACK);
                        }
                    }
                }
            }
        }
        paint.setStyle(Style.STROKE);
        canvas.drawText(titleTopSub, DEFAULT_PADDING_LENGTH, paint.getFontMetrics().bottom - paint.getFontMetrics().top + titleHeight, paint);
        int subTitleWidth = (int) paint.measureText(titleTopSub) + DEFAULT_PADDING_LENGTH * 2;
        int subTitleHeight = (int) (paint.getFontMetrics().bottom - paint.getFontMetrics().top + titleTopSubTextSize * 0.75);

        int width = titleWidth > subTitleWidth ? titleWidth : subTitleWidth;
        int height = titleHeight + subTitleHeight;
        return new Rect(0, 0, width, height);
    }

    /**
     * 绘制数据文字
     *
     * @param canvas
     * Canvas对象
     * @param rectF
     * Rect对象
     * @return
     * Rect对象
     */
    private Rect drawDataTitle(Canvas canvas, Rect rectF) {
        Paint paint = new Paint();
        float dataTitleTextSize = 23;
        if (dataTitleFont != null && !"".equals(dataTitleFont)) {
            if (dataTitleFont.indexOf(";") != -1) {
                String[] strs = dataTitleFont.split(";");
                for (String str : strs) {
                    if (str.startsWith("font-size")) {
                        int index = str.indexOf(":");
                        if (index == -1) continue;
                        String s = str.substring(index + 1).trim();
                        paint.setTextSize(Float.parseFloat(s.replace("px", "").trim()));
                        dataTitleTextSize = Float.parseFloat(s.replace("px", "").trim());
                    } else if (str.startsWith("style")) {
                        int index = str.indexOf(":");
                        if (index == -1)
                            continue;
                        String s = str.substring(index + 1).trim();
                        if ("bold".equals(s)) {
                            paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
                        } else if ("italic".equals(s)) {
                            paint.setTypeface(Typeface.defaultFromStyle(Typeface.ITALIC));
                        } else {
                            if (s.indexOf(",") != -1) {
                                if ("bold".equals(s.split(",")[0]) && "italic".equals(s.split(",")[1])) {
                                    paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD_ITALIC));
                                }
                                if ("bold".equals(s.split(",")[1]) && "italic".equals(s.split(",")[0])) {
                                    paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD_ITALIC));
                                }
                            }
                        }
                    } else if (str.startsWith("color")) {
                        int index = str.indexOf(":");
                        if (index == -1)
                            continue;
                        String s = str.substring(index + 1).trim();
                        if (CommonUtil.validRGBColor(s)) {
                            int r = Integer.parseInt(s.substring(0, 3));
                            int g = Integer.parseInt(s.substring(3, 6));
                            int b = Integer.parseInt(s.substring(6, 9));
                            paint.setColor(Color.rgb(r, g, b));
                        } else {
                            paint.setColor(Color.BLACK);
                        }
                    }
                }
            }
        }
        paint.setStyle(Style.STROKE);
        paint.setAntiAlias(true);
        Rect rect = new Rect(rectF);
        rect.set(rect.right + DEFAULT_PADDING_LENGTH, rect.top + radius + DEFAULT_PADDING_LENGTH, this.getWidth() - 25, rect.bottom + radius + DEFAULT_PADDING_LENGTH);
        if (datas.size() > 0) {
            String[] list = datas.keySet().toArray(new String[0]);
            Integer[] lengths = new Integer[list.length];
            for (int i = 0; i < list.length; i++) {
                lengths[i] = (int) paint.measureText(list[i]);
            }
            lengths = CommonUtil.sortDesc(lengths);
            int itemWidth = lengths[0];
            int itemHeight = (int) (paint.getFontMetrics().bottom - paint.getFontMetrics().top);
            int lineHeight = (int) (paint.getFontMetrics().bottom - paint.getFontMetrics().top + dataTitleTextSize * 0.75);
            int colsCount = rect.width() / (itemWidth + 25 * 2); //??
            int rowsCount = list.length / colsCount + ((list.length % colsCount) > 0 ? 1 : 0); //??
            rect.set(rect.right - (rect.right - DEFAULT_PADDING_LENGTH - radius * 2) / 2 - (itemWidth + DEFAULT_PADDING_LENGTH * 2), rect.top, rect.right, rect.top + lineHeight * list.length);
            for (int i = 0; i < list.length; i++) {
                canvas.drawText(list[i], rect.left + (itemWidth + DEFAULT_PADDING_LENGTH * 2) + DEFAULT_PADDING_LENGTH * 2, rect.top + lineHeight * i + itemHeight, paint);
                Paint p = new Paint();
                p.setColor(colors.get(i));
                p.setStyle(Style.FILL_AND_STROKE);
                p.setAntiAlias(true);
                canvas.drawCircle(rect.left + (itemWidth + DEFAULT_PADDING_LENGTH * 2) + DEFAULT_PADDING_LENGTH, rect.top + lineHeight * i + lineHeight / 2, 13, p);
            }
        }
        return rect;
    }

    /**
     * 绘制底部标题
     * @param canvas
     * Canvas对象
     * @param topHeight
     * */
    private Rect drawTitleBottom(Canvas canvas, int topHeight) {
        // 主标题
        Paint titlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        float titleTextSize = 30;
        if (titleFont != null && !"".equals(titleFont)) {
            if (titleFont.indexOf(";") != -1) {
                String[] strs = titleFont.split(";");
                for (String str : strs) {
                    if (str.startsWith("font-size")) {
                        int index = str.indexOf(":");
                        if (index == -1)
                            continue;
                        String s = str.substring(index + 1).trim();
                        titlePaint.setTextSize(Float.parseFloat(s.replace("px", "").trim()));
                        titleTextSize = Float.parseFloat(s.replace("px", "").trim());
                    } else if (str.startsWith("style")) {
                        int index = str.indexOf(":");
                        if (index == -1)
                            continue;
                        String s = str.substring(index + 1).trim();
                        if ("bold".equals(s)) {
                            titlePaint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
                        } else if ("italic".equals(s)) {
                            titlePaint.setTypeface(Typeface.defaultFromStyle(Typeface.ITALIC));
                        } else {
                            if (s.indexOf(",") != -1) {
                                if ("bold".equals(s.split(",")[0]) && "italic".equals(s.split(",")[1])) {
                                    titlePaint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD_ITALIC));
                                }
                                if ("bold".equals(s.split(",")[1]) && "italic".equals(s.split(",")[0])) {
                                    titlePaint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD_ITALIC));
                                }
                            }
                        }
                    } else if (str.startsWith("color")) {
                        int index = str.indexOf(":");
                        if (index == -1)
                            continue;
                        String s = str.substring(index + 1).trim();
                        if (CommonUtil.validRGBColor(s)) {
                            int r = Integer.parseInt(s.substring(0, 3));
                            int g = Integer.parseInt(s.substring(3, 6));
                            int b = Integer.parseInt(s.substring(6, 9));
                            titlePaint.setColor(Color.rgb(r, g, b));
                        } else {
                            titlePaint.setColor(Color.BLACK);
                        }
                    }
                }
            }
        }
        titlePaint.setStyle(Style.STROKE);

        // 副标题
        Paint subTitlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        float subTitleTextSize = 23;
        if (subTitleFont != null && !"".equals(subTitleFont)) {
            if (subTitleFont.indexOf(";") != -1) {
                String[] strs = subTitleFont.split(";");
                for (String str : strs) {
                    if (str.startsWith("font-size")) {
                        int index = str.indexOf(":");
                        if (index == -1) continue;
                        String s = str.substring(index + 1).trim();
                        subTitlePaint.setTextSize(Float.parseFloat(s.replace("px", "").trim()));
                        subTitleTextSize = Float.parseFloat(s.replace("px", "").trim());
                    } else if (str.startsWith("style")) {
                        int index = str.indexOf(":");
                        if (index == -1)
                            continue;
                        String s = str.substring(index + 1).trim();
                        if ("bold".equals(s)) {
                            subTitlePaint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
                        } else if ("italic".equals(s)) {
                            subTitlePaint.setTypeface(Typeface.defaultFromStyle(Typeface.ITALIC));
                        } else {
                            if (s.indexOf(",") != -1) {
                                if ("bold".equals(s.split(",")[0]) && "italic".equals(s.split(",")[1])) {
                                    subTitlePaint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD_ITALIC));
                                }
                                if ("bold".equals(s.split(",")[1]) && "italic".equals(s.split(",")[0])) {
                                    subTitlePaint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD_ITALIC));
                                }
                            }
                        }
                    } else if (str.startsWith("color")) {
                        int index = str.indexOf(":");
                        if (index == -1)
                            continue;
                        String s = str.substring(index + 1).trim();
                        if (CommonUtil.validRGBColor(s)) {
                            int r = Integer.parseInt(s.substring(0, 3));
                            int g = Integer.parseInt(s.substring(3, 6));
                            int b = Integer.parseInt(s.substring(6, 9));
                            subTitlePaint.setColor(Color.rgb(r, g, b));
                        } else {
                            subTitlePaint.setColor(Color.BLACK);
                        }
                    }
                }
            }
        }
        subTitlePaint.setStyle(Style.STROKE);

        int titleWidth = (int) titlePaint.measureText(title);
        int titleHeight = (int) (titlePaint.getFontMetrics().bottom - titlePaint.getFontMetrics().top + titleTextSize * 0.75);
        int subTitleWidth = (int) subTitlePaint.measureText(subTitle);
        int subTitleHeight = (int) (subTitlePaint.getFontMetrics().bottom - subTitlePaint.getFontMetrics().top + subTitleTextSize * 0.75);

        int top = topHeight + radius * 2 + DEFAULT_PADDING_LENGTH * 2;
        Rect rect = new Rect(DensityUtil.dip2px(ctx, 100), top, radius * 2 + DEFAULT_PADDING_LENGTH * 4, top + titleHeight + subTitleHeight);

        if (!title.equals("") || !subTitle.equals("")) {
            RectF bgRect = new RectF(rect.left + 5, rect.top + 5, rect.right - 5, rect.bottom - 5);
            Paint bgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            bgPaint.setColor(Color.WHITE);
            bgPaint.setStyle(Style.STROKE);
            canvas.drawText(title, DensityUtil.dip2px(ctx, 100) + (rect.width() - titleWidth) / 2, (int) (top + titleHeight - titleTextSize * 0.75), titlePaint);
            canvas.drawText(subTitle, DensityUtil.dip2px(ctx, 100) + (rect.width() - subTitleWidth) / 2, (int) (top + titleHeight + subTitleHeight - subTitleTextSize * 0.75), subTitlePaint);
        }
        return rect;
    }

    /**
     * 绘制外部黑圈
     *
     * @param canvas
     * Canvas对象
     */
    private void drawBorderCircle(Canvas canvas) {
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.rgb(40, 40, 40));
        paint.setStyle(Style.STROKE);
        paint.setStrokeWidth(20);
        canvas.drawCircle(centre.x, centre.y, radius + 20, paint);
    }

    /**
     * 绘制内部透明小圈
     *
     * @param canvas
     * Canvas对象
     */
    private void drawInsideBorderCircle(Canvas canvas) {
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.argb(36, 36, 36, 36));
        paint.setStyle(Style.STROKE);
        paint.setStrokeWidth(20);
        canvas.drawCircle(centre.x, centre.y, radius, paint);
    }

    /**
     * 绘制饼图圆
     * @param canvas
     * Canvas对象
     * */
    private void drawSumCircle(Canvas canvas) {
        if ("".equals(titleCenter)) {
            return;
        }
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.argb(36, 36, 36, 36));
        paint.setStyle(Style.FILL);
        canvas.drawCircle(centre.x, centre.y, (float) (radius * 0.3), paint);
        if (titleCenterFont != null && !"".equals(titleCenterFont)) {
            if (titleCenterFont.indexOf(";") != -1) {
                String[] strs = titleCenterFont.split(";");
                for (String str : strs) {
                    if (str.startsWith("font-size")) {
                        int index = str.indexOf(":");
                        if (index == -1) continue;
                        String s = str.substring(index + 1).trim();
                        paint.setTextSize(Float.parseFloat(s.replace("px", "").trim()));
                    } else if (str.startsWith("style")) {
                        int index = str.indexOf(":");
                        if (index == -1)
                            continue;
                        String s = str.substring(index + 1).trim();
                        if ("bold".equals(s)) {
                            paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
                        } else if ("italic".equals(s)) {
                            paint.setTypeface(Typeface.defaultFromStyle(Typeface.ITALIC));
                        } else {
                            if (s.indexOf(",") != -1) {
                                if ("bold".equals(s.split(",")[0]) && "italic".equals(s.split(",")[1])) {
                                    paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD_ITALIC));
                                }
                                if ("bold".equals(s.split(",")[1]) && "italic".equals(s.split(",")[0])) {
                                    paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD_ITALIC));
                                }
                            }
                        }
                    } else if (str.startsWith("color")) {
                        int index = str.indexOf(":");
                        if (index == -1)
                            continue;
                        String s = str.substring(index + 1).trim();
                        if (CommonUtil.validRGBColor(s)) {
                            int r = Integer.parseInt(s.substring(0, 3));
                            int g = Integer.parseInt(s.substring(3, 6));
                            int b = Integer.parseInt(s.substring(6, 9));
                            paint.setColor(Color.rgb(r, g, b));
                        } else {
                            paint.setColor(Color.WHITE);
                        }
                    }
                }
            }
        }
        canvas.drawText(titleCenter, centre.x - paint.measureText(titleCenter) / 2, centre.y + 8, paint);
    }

    /**
     * 绘制空心饼图空心圆
     * @param canvas
     * Canvas对象
     * */
    private void drawCenterCircle(Canvas canvas){
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.WHITE);
        paint.setStyle(Style.FILL);
        paint.setStrokeWidth((radius+20)/2);
        canvas.drawCircle(centre.x, centre.y, (radius+20)/2, paint);
    }

    /**
     * 绘制空心饼图内部阴影圆环
     * @param canvas
     * Canvas对象
     * */
    private void drawInCircle(Canvas canvas){
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.WHITE);
        paint.setAlpha(30);
        paint.setStrokeWidth(radius/2);
        canvas.drawCircle(centre.x, centre.y, (radius+20)/2+20, paint);
    }
    /**
     * 绘制饼图圆内扇形
     *
     * @param canvas
     * Canvas对象
     */
    private void drawDiagram(Canvas canvas) {
        if (datas.size() > 0) {
            ArrayList<String[]> list = new ArrayList<String[]>();
            String[] keys = datas.keySet().toArray(new String[0]);
            for (int i = 0; i < keys.length; i++) {
                list.add(datas.get(keys[i]));
            }
            boolean is100 = true;
            float sum = 0;
            if (isPerData) {
                for (int i = 0; i < list.size(); i++) {
                    if (sum >= 100) {
                        list.get(i)[2] = 0 + "";
                    }
                    if (sum + Float.parseFloat(list.get(i)[2]) >= 100) {
                        list.get(i)[2] = 100 - sum + "";
                        sum = 100;
                    }
                    if (sum < 100) {
                        sum = sum + Float.parseFloat(list.get(i)[2]);
                    }
                }
                if (sum < 100) {
                    is100 = false;
                    list.add(new String[]{"idnull", "", (100 - sum) + "", ""});
                }
                sum = 100;
            } else {
                for (int i = 0; i < list.size(); i++) {
                    sum = sum + Float.parseFloat(list.get(i)[2]);
                }
            }
            Paint mArcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mArcPaint.setStyle(Style.FILL);
            int offset = -90;
            float sumval = 0f;
            for (int i = 0; i < list.size(); i++) {
                if (!is100 && i == list.size() - 1) {
                    mArcPaint.setColor(Color.DKGRAY);
                } else {
                    mArcPaint.setColor(colors.get(i));
                }
                int sweep = Math.round(Float.parseFloat(list.get(i)[2]) / sum * 360f);
                canvas.drawArc(rect, offset, sweep-1, true, mArcPaint);
                angles.add(new Integer[]{offset, sweep});
                offset = offset + sweep;

                double value = Double.parseDouble(list.get(i)[2]);
                sumval = sumval + (float) value;
                float rate = (sumval - (float) value / 2) / sum;
                float offsetX;
                float offsetY;
                if (type==1){
                    offsetX = (float) (centre.x - radius * 0.5 * Math.sin(rate * -2 * Math.PI));
                    offsetY = (float) (centre.y - radius * 0.5 * Math.cos(rate * -2 * Math.PI));
                }
                else{
                    offsetX = (float) (centre.x - radius * 0.8 * Math.sin(rate * -2 * Math.PI));
                    offsetY = (float) (centre.y - radius * 0.8 * Math.cos(rate * -2 * Math.PI));

                }
                Paint mPaintFont = new Paint(Paint.ANTI_ALIAS_FLAG);
                if (perFont != null && !"".equals(perFont)) {
                    if (perFont.indexOf(";") != -1) {
                        String[] strs = perFont.split(";");
                        for (String str : strs) {
                            if (str.startsWith("font-size")) {
                                int index = str.indexOf(":");
                                if (index == -1) continue;
                                String s = str.substring(index + 1).trim();
                                mPaintFont.setTextSize(Float.parseFloat(s.replace("px", "").trim()));
                            } else if (str.startsWith("style")) {
                                int index = str.indexOf(":");
                                if (index == -1)
                                    continue;
                                String s = str.substring(index + 1).trim();
                                if ("bold".equals(s)) {
                                    mPaintFont.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
                                } else if ("italic".equals(s)) {
                                    mPaintFont.setTypeface(Typeface.defaultFromStyle(Typeface.ITALIC));
                                } else {
                                    if (s.indexOf(",") != -1) {
                                        if ("bold".equals(s.split(",")[0]) && "italic".equals(s.split(",")[1])) {
                                            mPaintFont.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD_ITALIC));
                                        }
                                        if ("bold".equals(s.split(",")[1]) && "italic".equals(s.split(",")[0])) {
                                            mPaintFont.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD_ITALIC));
                                        }
                                    }
                                }
                            } else if (str.startsWith("color")) {
                                int index = str.indexOf(":");
                                if (index == -1)
                                    continue;
                                String s = str.substring(index + 1).trim();
                                if (CommonUtil.validRGBColor(s)) {
                                    int r = Integer.parseInt(s.substring(0, 3));
                                    int g = Integer.parseInt(s.substring(3, 6));
                                    int b = Integer.parseInt(s.substring(6, 9));
                                    mPaintFont.setColor(Color.rgb(r, g, b));
                                } else {
                                    mPaintFont.setColor(Color.WHITE);
                                }
                            }
                        }
                    }
                }
                String desc = "";
                if (isPerData) {
                    desc = value + "%";
                } else {
                    desc = value + "";
                }
                float realx = 0;
                float realy = 0;
                if (offsetX < centre.x) {
                    realx = offsetX - mPaintFont.measureText(desc) + 15;
                } else if (offsetX > centre.x) {
                    realx = offsetX - 30;
                } else {
                    realx = offsetX - mPaintFont.measureText(desc) / 2;
                }
                if (offsetY > centre.y) {
                    if (value / sum < 0.2f) {
                        realy = offsetY + 10;
                    } else {
                        realy = offsetY + 5;
                    }
                } else if (offsetY < centre.y) {
                    if (value / sum < 0.2f) {
                        realy = offsetY - 10;
                    } else {
                        realy = offsetY + 5;
                    }
                } else {
                    realy = offsetY + 3;
                }

                canvas.drawText(desc, realx, realy, mPaintFont);
            }
        }
    }

    /**
     * 测量所需宽度和高度
     * @param widthMeasureSpec
     * 宽度
     * @param heightMeasureSpec
     * 高度
     * */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        this.setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
    }

    /**
     * 返回测量宽度
     * @param measureSpec
     * 传入的宽度值
     * @return
     * 测量宽度
     * */
    private int measureWidth(int measureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        } else if (specMode == MeasureSpec.AT_MOST) {
            result = Math.min(result, specSize);
        }
        return result;
    }

    /**
     * 返回测量高度
     * @param measureSpec
     * 传入的高度值
     * @return
     * 测量高度
     * */
    private int measureHeight(int measureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        } else if (specMode == MeasureSpec.AT_MOST) {
            result = Math.min(result, specSize);
        }
        return result;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        super.dispatchTouchEvent(event);
        String[] data = obtainOnClickSelectedArea(event);
        if (data == null) {
            try {
                if (click != null && !"".equals(click)) {
                    String str = "";
                    String vs[] = StringUtil.split(click, "||");
                    if (vs.length >= 1) {
                        String[] op = vs[0].split(":");
                        if (op.length >= 2) {
                            if (click.startsWith("PAGE")) {
                                str = "MEIP_PAGE=" + op[1] + "\r\n";
                            } else if (click.startsWith("OP")) {
                                str = "MEIP_ACTION=" + op[1] + "\r\n";
                            }
                            if (!str.equals("")) {
                                if (vs.length >= 2) {
                                    String[] args = StringUtil.split(vs[1], ",");
                                    for (String arg : args) {
                                        str += arg + "\r\n";
                                    }
                                }
                                Intent intent = new Intent();
                                intent.setAction(StaticObject.ismenuclick == true ? StaticObject.MENU_CLICK_ACTION : StaticObject.CLICK_ACTION);
                                intent.putExtra("meip", str);
                                LocalBroadcastManager
                                        .getInstance(ctx).sendBroadcast(intent);
                            }
                        }
                    }
                }
            } catch (Throwable e) {
                String clsName = this.getClass().getName();
                clsName = clsName.substring(clsName.lastIndexOf(".") + 1);
                String info = ctx.getString(R.string.axeac_toast_exp_click);
                Toast.makeText(ctx, clsName + info, Toast.LENGTH_SHORT).show();
            }
        } else {
            if (itemClicks.size() > 0) {
                try {
                    CustomDialog.Builder btnsDialog = new CustomDialog.Builder(ctx);
                    btnsDialog.setTitle(R.string.axeac_msg_choice);
                    btnsDialog.setCancelable(false);
                    btnsDialog.setNegativeButton(R.string.axeac_msg_cancel, new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            dialog.dismiss();
                        }
                    });
                    ListView lv = new ListView(ctx);
                    lv.setBackgroundColor(Color.WHITE);
                    lv.setCacheColorHint(Color.TRANSPARENT);
                    lv.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
                    btnsDialog.setContentView(lv);
                    btnsDialog.setNeutralButton(R.string.axeac_msg_cancel, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                        }
                    });
                    CustomDialog dialog = btnsDialog.create();
                    List<String> vals = new ArrayList<String>();
                    for (String d : data) {
                        vals.add(d);
                    }
                    lv.setAdapter(new OptionAdapter(ctx, itemClicks, dialog, vals));
                    dialog.show();
                } catch (Throwable e) {
                    String clsName = this.getClass().getName();
                    clsName = clsName.substring(clsName.lastIndexOf(".") + 1);
                    String info = ctx.getString(R.string.axeac_toast_exp_click);
                    Toast.makeText(ctx, clsName + info, Toast.LENGTH_SHORT).show();
                }
            } else {
                Toast.makeText(ctx, data[3], Toast.LENGTH_SHORT).show();
            }
        }
        return false;
    }

    /**
     * 判断点击手势是否在饼图内,并返回点击处设置的数据
     * @param event
     * MotionEvent对象
     * @return
     * 包含数据的String数组
     * */
    private String[] obtainOnClickSelectedArea(MotionEvent event) {
        String[] data = null;
        int index = -1;
        boolean isInsideCircle = false;
        ArrayList<String[]> list = new ArrayList<String[]>();
        String[] keys = datas.keySet().toArray(new String[0]);
        for (int i = 0; i < keys.length; i++) {
            list.add(datas.get(keys[i]));
        }
        for (int i = 0; i < list.size(); i++) {

            if (type==1){
                // To determine whether it is in the circle
                // 判断是否在圆内
                isInsideCircle = (event.getX() - centre.x) * (event.getX() - centre.x)
                        + (event.getY() - centre.y) * (event.getY() - centre.y)
                        <= radius * radius ? true : false;
            }else{
                // To determine whether it is in the circle
                //判断是否在圆内
                isInsideCircle = (event.getX() - centre.x) * (event.getX() - centre.x)
                        + (event.getY() - centre.y) * (event.getY() - centre.y)
                        <= (radius+10)* (radius+10)&&(event.getX() - centre.x) * (event.getX() - centre.x)
                        + (event.getY() - centre.y) * (event.getY() - centre.y)
                        >= ((radius+20)/2+20)* ((radius+20)/2+20) ? true : false;
            }

            if (isInsideCircle) {
                float tanX = (event.getY() - centre.y) / (event.getX() - centre.x);
                double angle = Math.atan(tanX) * 180 / Math.PI;
                /**
                 * describe:Second quadrant | first quadrant
                 *         -----------------------------------
                 *          Third quadrant | fourth quadrant
                 *
                 * 描述: 第二象限|第一象限
                 *       ------------------
                 *        第三象限|第四象限
                 */
                if (event.getY() <= centre.y && event.getX() > centre.x) {
                    // First quadrant area
                    // 第一象限区域内
                } else if (event.getY() <= centre.y && event.getX() < centre.x) {
                    // Second quadrant area
                    // 第二象限区域内
                    angle += 180;
                } else if (event.getY() > centre.y && event.getX() < centre.x) {
                    // Third quadrant area
                    // 第三象限区域内
                    angle += 180;
                } else if (event.getY() > centre.y && event.getX() > centre.x) {
                    // Fourth quadrant area
                    // 第四象限区域内
                }
                if (angle >= angles.get(i)[0] && angle <= angles.get(i)[0] + angles.get(i)[1]) {
                    index = i;
                    break;
                }
            }
        }
        if (index != -1) {
            data = list.get(index);
        }
        return data;
    }

    public View getView() {
        return this;
    }
}

其中饼图数据格式为:id||name||num||toast" 

id:不同数据项的id

name:扇形区域代表的名称

num:数据大小

toast:点击扇形区域显示的弹出文本

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值