在android中的饼图上单击事件

时间:2012-01-24 04:24:29

标签: android charts pie-chart

我习惯用画布绘制饼图.. 饼图中有大约10个弧。我想在每个弧上执行点击事件。 有没有办法做到这一点?或任何其他方式?

这是我的饼图视图..

MyView.java

package android.piechart;
import java.util.ArrayList;
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.util.Log;
import android.view.View;

public class MyView extends View {

private Paint p;
private int startX;
private int startY;
private int radius;
private ArrayList<Integer> colors;
private ArrayList<Integer> values;

public MyView(Context context, AttributeSet attrs) {
    super(context, attrs);
    p = new Paint();
    p.setColor(Color.BLUE);
    p.setAntiAlias(true);

    colors = new ArrayList<Integer>();
    values = new ArrayList<Integer>();

    startX = 320 / 4;
    startY = 480 / 8;
    radius = 320 / 2;

    colors.add(Color.GREEN);
    colors.add(Color.CYAN);
    colors.add(Color.MAGENTA);
    colors.add(Color.BLUE);
    colors.add(Color.RED);

    values.add(0);
    values.add(1);
    values.add(3);
    values.add(0);
    values.add(2);

}

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

    Log.e("", "onDraw() is called...");

    float offset = 0;
    float sum = 0;
    for (int a = 0; a < values.size(); a++) {
        sum += values.get(a);
    }

    float angle = (float) (360 / sum);

    Log.e("angle", "" + angle);

    RectF rectF = new RectF();
    rectF.set(getStartX(), getStartY(), getStartX() + getRadius(),
            getStartY() + getRadius());

    for (int i = 0; i < values.size(); i++) {

        p.setColor(colors.get(i));

        if (i == 0) {
            canvas.drawArc(rectF, 0, values.get(i) * angle, true, p);
        } else {
            canvas.drawArc(rectF, offset, values.get(i) * angle, true, p);
        }

        offset += (values.get(i) * angle);
    }

    canvas.save();
}

public int getStartX() {
    return startX;
}

public void setStartX(int startX) {
    this.startX = startX;
}

public int getStartY() {
    return startY;
}

public void setStartY(int startY) {
    this.startY = startY;
}

public int getRadius() {
    return radius;
}

public void setRadius(int radius) {
    this.radius = radius;
}

public ArrayList<Integer> getColors() {
    return colors;
}

public void setColors(ArrayList<Integer> colors) {
    this.colors = colors;
}

public ArrayList<Integer> getValues() {
    return values;
}

public void setValues(ArrayList<Integer> values) {
    this.values = values;
}
}

提前致谢..

2 个答案:

答案 0 :(得分:13)

我自己解决了我的问题......

MyView.java

public class MyView extends View {

private Paint p;
private int startX;
private int startY;
private int radius;
private ArrayList<Integer> colors;
private ArrayList<Float> values;
Bitmap bitmap;
Context mContext;

public MyView(Context context, AttributeSet attrs) {
    super(context, attrs);

    mContext = context;

    p = new Paint();
    p.setAntiAlias(true);

    colors = new ArrayList<Integer>();
    values = new ArrayList<Float>();

    startX = 320 / 4;
    startY = 480 / 8;
    radius = 320 / 2;

    colors.add(Color.GREEN);
    colors.add(Color.CYAN);
    colors.add(Color.MAGENTA);
    colors.add(Color.BLUE);
    colors.add(Color.RED);

    values.add(5f);
    values.add(1f);
    values.add(3f);
    values.add(5f);
    values.add(2f);

}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    bitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(),
            Bitmap.Config.ARGB_8888);

    Canvas c = new Canvas(bitmap);

    Log.e("", "onDraw() is called...");

    float offset = 0;
    float sum = 0;
    for (int a = 0; a < values.size(); a++) {
        sum += values.get(a);
    }

    float angle = (float) (360 / sum);

    Log.e("angle", "" + angle);

    RectF rectF = new RectF();
    rectF.set(getStartX(), getStartY(), getStartX() + getRadius(),
            getStartY() + getRadius());

    for (int i = 0; i < values.size(); i++) {

        p.setColor(colors.get(i));

        if (i == 0) {
            canvas.drawArc(rectF, 0, values.get(i) * angle, true, p);
            c.drawArc(rectF, 0, values.get(i) * angle, true, p);
        } else {
            canvas.drawArc(rectF, offset, values.get(i) * angle, true, p);
            c.drawArc(rectF, offset, values.get(i) * angle, true, p);
        }

        offset += (values.get(i) * angle);
    }

    canvas.save();

}

@Override
public boolean onTouchEvent(MotionEvent event) {

    int color = bitmap.getPixel((int) event.getX(), (int) event.getY());

    Log.e("", "" + color);

    if (colors.contains(color)) {
        Log.e("", "is matching");
        if (color == Color.RED) {
            Toast.makeText(mContext, "Is Red", Toast.LENGTH_SHORT).show();
        }

        if (color == Color.CYAN) {
            Toast.makeText(mContext, "Is Cyan", Toast.LENGTH_SHORT).show();
        }

        if (color == Color.MAGENTA) {
            Toast.makeText(mContext, "Is MAGENTA", Toast.LENGTH_SHORT)
                    .show();
        }
        if (color == Color.BLUE) {
            Toast.makeText(mContext, "Is BLUE", Toast.LENGTH_SHORT).show();
        }
        if (color == Color.GREEN) {
            Toast.makeText(mContext, "Is GREEN", Toast.LENGTH_SHORT).show();
        }
    }

    return super.onTouchEvent(event);
}

public int getStartX() {
    return startX;
}

public void setStartX(int startX) {
    this.startX = startX;
}

public int getStartY() {
    return startY;
}

public void setStartY(int startY) {
    this.startY = startY;
}

public int getRadius() {
    return radius;
}

public void setRadius(int radius) {
    this.radius = radius;
}

public ArrayList<Integer> getColors() {
    return colors;
}

public void setColors(ArrayList<Integer> colors) {
    this.colors = colors;
}

public ArrayList<Float> getValues() {
    return values;
}

public void setValues(ArrayList<Float> values) {
    this.values = values;
}

}

我希望它对其他人有用......

答案 1 :(得分:3)

如果您使用了Canvas,则可能会引用其基础Bitmap。您可以使用Bitmap.getPixel(int x, int y)并测试它返回的颜色,以确定点击所在的部分。

否则,您必须手动进行计算,以确定哪个楔形包含您点击的x,y坐标。