如下图这样的一个饼图效果,看上去很简单,不如让我们用Android自定义控件的知识来实现它
public class PieChartView extends View
private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final float RADIUS = HenUtil.dp2px(100);//饼图的半径
private final int[] colors = new int[]{Color.BLUE, Color.CYAN, Color.RED, Color.BLACK};//四个饼图的颜色
private final int[] degrees = new int[]{60, 150, 90, 60};//四个饼图的角度,总和为360°
private final float OFFSET = HenUtil.dp2px(6);//被抽出来的那个饼图偏出的位移
代码如下:
@Override
protected void onDraw(Canvas canvas) {
int startAngle = 0;
for (int i = 0; i < 4; i++) {
paint.setColor(colors[i]);
float baseX, baseY;
if (i == 2) {
baseX = (float) (getWidth() / 2f + OFFSET * Math.cos(Math.toRadians(startAngle + degrees[i] / 2f)));
baseY = (float) (getHeight() / 2f + OFFSET * Math.sin(Math.toRadians(startAngle + degrees[i] / 2f)));
} else {
baseX = getWidth() / 2f;
baseY = getHeight() / 2f;
}
canvas.drawArc(baseX - RADIUS, baseY - RADIUS,
baseX + RADIUS, baseY + RADIUS, startAngle, degrees[i], true, paint);
startAngle += degrees[i];
}
}
for (int i = 0; i < 4; i++) {
paint.setColor(colors[i]);
float baseX, baseY;
if (i == 2) {
baseX = (float) (getWidth() / 2f + OFFSET * Math.cos(Math.toRadians(startAngle + degrees[i] / 2f)));
baseY = (float) (getHeight() / 2f + OFFSET * Math.sin(Math.toRadians(startAngle + degrees[i] / 2f)));
} else {
baseX = getWidth() / 2f;
baseY = getHeight() / 2f;
}
canvas.drawArc(baseX - RADIUS, baseY - RADIUS,
baseX + RADIUS, baseY + RADIUS, startAngle, degrees[i], true, paint);
startAngle += degrees[i];
}
float baseX, baseY;
if (i == 2) {
baseX = (float) (getWidth() / 2f + OFFSET * Math.cos(Math.toRadians(startAngle + degrees[i] / 2f)));
baseY = (float) (getHeight() / 2f + OFFSET * Math.sin(Math.toRadians(startAngle + degrees[i] / 2f)));
}
如果是第三个扇形,扇形的圆心要做一个小偏移,模型示意图:
就是把起始角度+当前扇形角度一半作为计算x方向和y方向偏移的角度值
,然后
偏移长度*cos(偏移角度)= x方向偏移距离
偏移长度*sin(偏移角度)= y方向偏移距离
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.Nullable;
import com.example.hencoder.HenUtil;
public class PieChartView extends View {
private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final float RADIUS = HenUtil.dp2px(100);//饼图的半径
private final int[] colors = new int[]{Color.BLUE, Color.CYAN, Color.RED, Color.BLACK};//四个饼图的颜色
private final int[] degrees = new int[]{60, 150, 90, 60};//四个饼图的角度,总和为360°
private final float OFFSET = HenUtil.dp2px(6);//被抽出来的那个饼图偏出的位移
public PieChartView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
int startAngle = 0;
for (int i = 0; i < 4; i++) {
paint.setColor(colors[i]);
float baseX, baseY;
if (i == 2) {
baseX = (float) (getWidth() / 2f + OFFSET * Math.cos(Math.toRadians(startAngle + degrees[i] / 2f)));
baseY = (float) (getHeight() / 2f + OFFSET * Math.sin(Math.toRadians(startAngle + degrees[i] / 2f)));
} else {
baseX = getWidth() / 2f;
baseY = getHeight() / 2f;
}
canvas.drawArc(baseX - RADIUS, baseY - RADIUS,
baseX + RADIUS, baseY + RADIUS, startAngle, degrees[i], true, paint);
startAngle += degrees[i];
}
}
}