从3分得到一个矩形

时间:2014-06-11 06:56:59

标签: android android-canvas

我正在制作一个饼图,每个饼图上都有一个文字。为了使每个饼图上的文本居中,我需要一个下面解释的Rect对象:

这是一个示例饼图:

enter image description here

你可以看到4个点:中心和与饼图圆周相交的三个点三行:

enter image description here

现在要将文本居中放在每个饼图上,我想为每个文本制作3个Rect对象:

enter image description here

我不想绘制任何矩形,但需要一个与这些点对应的Rect对象。每个Rect必须包含圆圈上相应的饼图切片所做的交点,即圆心。知道怎么做吗?我希望我的问题清楚。

我的饼图代码:

public class PieView extends View {

String[] names;
int values[];

public PieView(Context context) {
    super(context);
}

public PieView(Context context, int nums[], String nam[]) {
    super(context);
    names = nam;
    values = nums;
}

@Override
protected void onDraw(Canvas canvas) {
    DecimalFormat df = new DecimalFormat("#.00");
    super.onDraw(canvas);
    int radius = getHeight() / 2;
    int total = sum(values);
    String percentage[] = { df.format((values[0] * 100) / total),
            df.format((values[1] * 100) / total),
            df.format((values[2] * 100) / total) };
    Paint green = new Paint();
    Paint red = new Paint();
    Paint blue = new Paint();
    blue.setAntiAlias(true);
    green.setAntiAlias(true);
    red.setAntiAlias(true);
    blue.setColor(Color.parseColor("#30abd9"));
    green.setColor(Color.parseColor("#30d976"));
    red.setColor(Color.parseColor("#db7a26"));
    blue.setStyle(Paint.Style.FILL);
    green.setStyle(Paint.Style.FILL);
    red.setStyle(Paint.Style.FILL);
    RectF rectf = new RectF(
            new Rect(getWidth() / 2 - radius, getHeight() / 2 - radius,
                    getWidth() / 2 + radius, getHeight() / 2 + radius));
    canvas.drawArc(rectf, 0, (values[0] * 360) / total, true, blue);
    canvas.drawArc(rectf, (values[0] * 360) / total, (values[1] * 360)
            / total, true, green);
    canvas.drawArc(rectf, ((values[0] * 360) / total)
            + ((values[1] * 360) / total),
            360 - (((values[0] * 360) / total) + ((values[1] * 360))
                    / total), true, red);
    Paint eraserPaint = new Paint();
    eraserPaint.setColor(Color.parseColor("#f2f2f2"));
    eraserPaint.setStrokeWidth(3);
    canvas.drawLine(getWidth() / 2, getHeight() / 2, getWidth() / 2
            + radius, getHeight() / 2, eraserPaint);
    canvas.drawLine(
            (float) getWidth() / 2,
            (float) getHeight() / 2,
            (float) (getWidth() / 2 + radius
                    * (Math.cos(Math.toRadians((values[0] * 360) / total)))),
            (float) (getHeight() / 2 + radius
                    * Math.sin(Math.toRadians((values[0] * 360) / total))),
            eraserPaint);
    canvas.drawLine(
            (float) getWidth() / 2,
            (float) getHeight() / 2,
            (float) (getWidth() / 2 + radius
                    * (Math.cos(Math.toRadians(((values[0] * 360) / total)
                            + ((values[1] * 360) / total))))),
            (float) (getHeight() / 2 + radius
                    * Math.sin(Math.toRadians(((values[0] * 360) / total)
                            + ((values[1] * 360) / total)))), eraserPaint);
    // if (values[0] != 0) {
    // Rect areaRect1 = new Rect(getWidth()/2, 90,
    // columnsAreaWidth + widthLeft + 15, 130);
    // canvas.drawRect(areaRect1, eraserPaint);
    // RectF bounds1 = new RectF(areaRect1);
    // bounds1.right = eraserPaint.measureText("Easy\n"+values[0], 0, new
    // String(
    // "Easy\n"+values[0]).length());
    // // measure text height
    // bounds1.bottom = eraserPaint.descent() - eraserPaint.ascent();
    // bounds1.left += (areaRect1.width() - bounds1.right) / 2.0f;
    // bounds1.top += (areaRect1.height() - bounds1.bottom) / 2.0f;
    // canvas.drawText("Easy\n"+values[0], bounds1.left,
    // bounds1.top - eraserPaint.ascent(), eraserPaint);
    //
    // }
}

@Override
public void setLayoutParams(LayoutParams params) {
    super.setLayoutParams(params);
}

private int sum(int[] num) {
    int x = 0;
    for (int i = 0; i < num.length; i++) {
        x += num[i];
    }
    return x;
}
}

注释代码用于文本。我需要Rect对象。

1 个答案:

答案 0 :(得分:1)

感谢@pskink,我得到了答案。这是我的饼图的完整代码。我只为3个值制作了它,但它可以通用,几乎没有变化。希望它可能对某人有用:)

package com.utils;

import org.json.JSONArray;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.view.View;
import android.view.ViewGroup.LayoutParams;

public class ColumnsView extends View {

JSONArray array;

public ColumnsView(Context context) {
    super(context);
}

public ColumnsView(Context context, JSONArray jar) {
    super(context);
    array = jar;
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    Paint green = new Paint();
    Paint red = new Paint();
    Paint grey = new Paint();
    Paint textColor = new Paint();
    textColor.setColor(Color.parseColor("#b8b8b8"));
    textColor.setStrokeWidth(5);
    textColor.setTextSize(25);
    grey.setColor(Color.parseColor("#e1e1e1"));
    green.setColor(Color.parseColor("#91cc33"));
    red.setColor(Color.parseColor("#d93030"));
    grey.setStyle(Paint.Style.FILL);
    red.setStyle(Paint.Style.FILL);
    green.setStyle(Paint.Style.FILL);
    int width = getWidth();
    int columnsAreaWidth = width - 200;
    int columnHeight = 240;
    int columnWidth = columnsAreaWidth / (array.length() + 1);
    int gapWidth = columnWidth / array.length();
    try {
        int freeWidth = gapWidth;
        for (int i = 0; i < array.length(); i++) {
            int total = Integer.parseInt(array.getJSONObject(i).getString(
                    "Total"));
            int correct = Integer.parseInt(array.getJSONObject(i)
                    .getString("Correct"));
            int incorrect = Integer.parseInt(array.getJSONObject(i)
                    .getString("Incorrect"));
            int unattempted = Integer.parseInt(array.getJSONObject(i)
                    .getString("Unattempted"));
            String name = array.getJSONObject(i).getString("Level");
            int correctHeight = (columnHeight * correct) / total;
            int unattemptedHeight = (columnHeight * unattempted) / total;
            int incorrectHeight = columnHeight - correctHeight
                    - unattemptedHeight;
            canvas.drawRect(freeWidth, 0, freeWidth + columnWidth,
                    correctHeight, green);
            canvas.drawRect(freeWidth, correctHeight, freeWidth
                    + columnWidth, correctHeight + unattemptedHeight, grey);
            canvas.drawRect(freeWidth, correctHeight + unattemptedHeight,
                    freeWidth + columnWidth, columnHeight, red);
            int xPos = (canvas.getWidth() / 2);
            Rect areaRect = new Rect(freeWidth - gapWidth,
                    columnHeight + 10, freeWidth + columnWidth + gapWidth,
                    columnHeight + 40);
            RectF bounds = new RectF(areaRect);
            bounds.right = textColor.measureText(name, 0, name.length());
            bounds.bottom = textColor.descent() - textColor.ascent();
            bounds.left += (areaRect.width() - bounds.right) / 2.0f;
            bounds.top += (areaRect.height() - bounds.bottom) / 2.0f;
            canvas.drawText(name, bounds.left,
                    bounds.top - textColor.ascent(), textColor);
            // canvas.drawText(name, freeWidth + 10, 300 + 40, textColor);
            freeWidth += columnWidth + gapWidth;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    int widthLeft = 180;
    canvas.drawRect(new RectF(new Rect(columnsAreaWidth + 15, 30,
            columnsAreaWidth + 15 + 40, 70)), green);
    canvas.drawRect(new RectF(new Rect(columnsAreaWidth + 15, 90,
            columnsAreaWidth + 15 + 40, 130)), grey);
    canvas.drawRect(new RectF(new Rect(columnsAreaWidth + 15, 150,
            columnsAreaWidth + 15 + 40, 190)), red);
    grey.setStyle(Paint.Style.STROKE);
    red.setStyle(Paint.Style.STROKE);
    green.setStyle(Paint.Style.STROKE);
    canvas.drawRect(new RectF(new Rect(columnsAreaWidth + 15, 30,
            columnsAreaWidth + 15 + 40, 70)), green);
    canvas.drawRect(new RectF(new Rect(columnsAreaWidth + 15, 90,
            columnsAreaWidth + 15 + 40, 130)), grey);
    canvas.drawRect(new RectF(new Rect(columnsAreaWidth + 15, 150,
            columnsAreaWidth + 15 + 40, 190)), red);
    green.setTextSize(20);
    red.setTextSize(20);
    grey.setTextSize(20);
    Rect areaRect = new Rect(columnsAreaWidth + 15 + 40, 30,
            columnsAreaWidth + widthLeft + 15, 70);
    canvas.drawRect(areaRect, green);
    RectF bounds = new RectF(areaRect);
    bounds.right = green.measureText("Correct", 0,
            new String("Correct").length());
    // measure text height
    bounds.bottom = green.descent() - green.ascent();
    bounds.left += (areaRect.width() - bounds.right) / 2.0f;
    bounds.top += (areaRect.height() - bounds.bottom) / 2.0f;
    canvas.drawText("Correct", bounds.left, bounds.top - green.ascent(),
            green);
    Rect areaRect2 = new Rect(columnsAreaWidth + 15 + 40, 90,
            columnsAreaWidth + widthLeft + 15, 130);
    canvas.drawRect(areaRect2, grey);
    RectF bounds2 = new RectF(areaRect2);
    bounds2.right = grey.measureText("Unattempted", 0, new String(
            "Unattempted").length());
    // measure text height
    bounds2.bottom = grey.descent() - grey.ascent();
    bounds2.left += (areaRect2.width() - bounds2.right) / 2.0f;
    bounds2.top += (areaRect2.height() - bounds2.bottom) / 2.0f;
    canvas.drawText("Unattempted", bounds2.left,
            bounds2.top - grey.ascent(), grey);
    Rect areaRect3 = new Rect(columnsAreaWidth + 15 + 40, 150,
            columnsAreaWidth + widthLeft + 15, 190);
    canvas.drawRect(areaRect3, red);
    RectF bounds3 = new RectF(areaRect3);
    bounds3.right = red.measureText("Incorrect", 0,
            new String("Incorrect").length());
    // measure text height
    bounds3.bottom = red.descent() - red.ascent();
    bounds3.left += (areaRect3.width() - bounds3.right) / 2.0f;
    bounds3.top += (areaRect3.height() - bounds3.bottom) / 2.0f;
    canvas.drawText("Incorrect", bounds3.left, bounds3.top - red.ascent(),
            red);
}

@Override
public void setLayoutParams(LayoutParams params) {
    super.setLayoutParams(params);
}
}

截图: enter image description here