一个简单的饼状图的绘制!

本文介绍如何在Android中创建一个自定义的饼状图。通过定义PieData类存储参数,并扩展View类实现PieView,详细展示了绘制饼状图的过程。在布局文件中,可以轻松添加PieView组件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先我们需要定义个数据类来放置需要的参数,然后我们就需要确定我们需要那些参数!

/**
* Created by ML on 2016/12/29.
* 饼图统计图
*/

public class PieData {

//用户关心
private String pieName;   // 名字
private float value;        // 数值
private float percentage;   //百分比

//用户不关心
private int pieColor = 0;  //颜色
private float pieAngle = 0;  //角度


public PieData(@NonNull String pieName,@NonNull float value) {
    this.pieName = pieName;
    this.value = value;
}

public String getPieName() {
    return pieName;
}

public void setPieName(String pieName) {
    this.pieName = pieName;
}

public float getValue() {
    return value;
}

public void setValue(float value) {
    this.value = value;
}

public float getPercentage() {
    return percentage;
}

public void setPercentage(float percentage) {
    this.percentage = percentage;
}

public int getPieColor() {
    return pieColor;
}

public void setPieColor(int pieColor) {
    this.pieColor = pieColor;
}

public float getPieAngle() {
    return pieAngle;
}

public void setPieAngle(float pieAngle) {
    this.pieAngle = pieAngle;
}

之后就是自定义View绘制图形了:

/**
* Created by ML on 2016/12/29.
*/

public class PieView extends View {

private Paint mPaint;

// 颜色表(注意: 此处定义颜色使用的是ARGB,带Alpha通道的)
private int[] mColors = {0xFFCCFF00, 0xFF6495ED, 0xFFE32636, 0xFF800000, 0xFF808000, 0xFFFF8C69, 0xFF808080,
        0xFFE6B800, 0xFF7CFC00};

private ArrayList<PieData> mPieDatas = new ArrayList<>();

private float startAngle = 0;  //绘制扇形开始角度

private int viewWidth;
private int viewHight;


/**
 * 构造方法
 *
 * @param context
 */
public PieView(Context context) {
    this(context, null);

}

public PieView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initPaint();
}

public void initPaint() {
    mPaint = new Paint();
    mPaint.setColor(Color.BLACK);
    mPaint.setStyle(Paint.Style.FILL);
    mPaint.setStrokeWidth(10);
    mPaint.setAntiAlias(true);   //防止边缘锯齿!
}

/**
 * 测量View的大小
 *
 * @param widthMeasureSpec
 * @param heightMeasureSpec
 */
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

}

/**
 * 确定View的大小
 *
 * @param w
 * @param h
 * @param oldw
 * @param oldh
 */
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    viewWidth = w;
    viewHight = h;
}

/**
 * 确定子View的布局
 *
 * @param changed
 * @param left
 * @param top
 * @param right
 * @param bottom
 */
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    super.onLayout(changed, left, top, right, bottom);


}

public void setStartAngle(float startAngle) {
    this.startAngle = startAngle;
    invalidate();
}

public void setPieDatas(ArrayList<PieData> pieDatas) {
    this.mPieDatas = pieDatas;
    initData(mPieDatas);
    invalidate();
}

private void initData(ArrayList<PieData> pieDatas) {

    if (pieDatas == null || pieDatas.size() == 0) {
        return;
    }

    float allValue = 0;
    float allAngle = 0;
    for (int i = 0; i < pieDatas.size(); i++) {
        PieData data = pieDatas.get(i);
        allValue += data.getValue();
        int j = i % mColors.length;
        data.setPieColor(mColors[j]);
    }

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

        PieData data = pieDatas.get(i);
        float percentage = data.getValue() / allValue;
        float angle = percentage * 360;

        data.setPieAngle(angle);
        data.setPercentage(percentage);
        allAngle += angle;
        Log.i("angle", "" + data.getPieAngle());
    }
    Log.e("allAngle", allAngle + "");
}


/**
 * 绘制图形
 *
 * @param canvas
 */
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if (mPieDatas == null || mPieDatas.size() == 0) {
        return;
    }

    float currentStartAngle = startAngle;
    canvas.translate(viewWidth / 2, viewHight / 2);  //将画布的坐标原点移动到中心位置!
    float r = (float) (Math.min(viewWidth, viewHight) / 2 * 0.8); //饼状图的半径
    RectF rect = new RectF(-r, -r, r, r);   //根据半径得到矩形

    for (PieData data : mPieDatas) {    //循环绘制扇形饼图
        mPaint.setColor(data.getPieColor());
        canvas.drawArc(rect, currentStartAngle, data.getPieAngle(), true, mPaint);
        currentStartAngle += data.getPieAngle();
    }
}
/*对外提供设置数据接口*/
上面已经注释了一些关键的地方,剩下的都是挺简单的逻辑问题就不多说了,最后就是在布局中使用或者在代码中使用都可以!
public class MainActivity extends AppCompatActivity {


private ArrayList<PieData> mPieDatas = new ArrayList<>();

private PieView mPieView;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    final PieView view = new PieView(this);
    setContentView(R.layout.activity_main);
    initData();
    mPieView = (PieView) findViewById(R.id.pieView);
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            mPieView.setPieDatas(mPieDatas);
        }
    }, 50);
}

private void initData() {
    mPieDatas.add(new PieData("土建一部", 100));
    mPieDatas.add(new PieData("土建二部", 200));
    mPieDatas.add(new PieData("土建三部", 300));
    mPieDatas.add(new PieData("安装一部", 400));
    mPieDatas.add(new PieData("安装二部", 500));
    mPieDatas.add(new PieData("市政工程部", 600));
    mPieDatas.add(new PieData("招标代理部", 700));
}

}
或者:
com.example.a20161005.custormview.PieChartView.PieView
android:id=”@+id/pieView”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
/>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值