Android   发布时间:2022-04-28  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Android甜甜圈图表大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我创建了一个圆环图,如下所示:

我的结果甜甜圈图应该采用以下方式:

我的问题是,我如何实现图像线条(在第二个屏幕截图中四舍五入)

供参,这是我写的代码

public class PieChartView extends View {

privatE int[] values = {30,60,90,100,150};
privatE int c[] = {Color.MAGENTA,Color.bLUE,Color.RED,Color.CYAN,Color.YELLOW};
privatE int valuesLength = values.length;
private RectF rectF;
private Paint slicePaint,textPaint;
private Path path;

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

    valuesLength = values.length;
    slicePaint = new Paint();
    slicePaint.setAntiAlias(true);
    slicePaint.setDither(true);
    slicePaint.setStyle(Paint.Style.FILL);

    path = new Path();
}

@SuppressLint("DrawAlLOCATIOn")
@Override
protected void onDraw(Canvas canvas) {
    if(values != null) {
        int startTop = 0;
        int startLeft = 0;
        int endBottom = getHeight();
        int endRight = endBottom;// This makes an equal square.

        rectF = new RectF(startLeft,startTop,endRight,endBottom);

        float[] scaledValues = scale();
        float sliceStartPoint = 0;
        path.addCircle(rectF.centerX(),rectF.centerY(),125,Direction.CW);
        canvas.clipPath(path,Op.DIFFERENCE);

        for(int i = 0; i < valuesLength; i++) {
            slicePaint.setColor(c[i]);
            path.reset();
            path.addArc(rectF,sliceStartPoint,scaledValues[i]);
            path.lineTo(rectF.centerX(),rectF.centerY());
            canvas.drawPath(path,slicePaint);
            sliceStartPoint += scaledValues[i];//This updates the starTing point of next slice.
        }
    }
}
private float[] scale() {
    float[] scaledValues = new float[this.values.length];
    float @R_272_10586@l = get@R_272_10586@l(); //@R_272_10586@l all values supplied to the chart
    for (int i = 0; i < this.values.length; i++) {
        scaledValues[i] = (this.values[i] / @R_272_10586@l) * 360; //Scale each value
    }
    return scaledValues;
}

 private float get@R_272_10586@l() {
        float @R_272_10586@l = 0;
        for (float val : this.values)
            @R_272_10586@l += val;
        return @R_272_10586@l;
    }

}

另外,如何从一个角度(开始或扫描角度)找出坐标.如果我想从圆心到坐标绘制一条线?

解决方法

这是我在这个图书馆 https://github.com/Ken-Yang/AndroidPieChart的帮助下经过两天的搜索后最终做到的

以及在朋友的帮助和很多搜索中完成文本中心的方程式

如果您正在使用片段,请在MainActivity onCreate或oncreateView上:

PieChart pie = (PieChart) rootView.findViewById(R.id.pieChart);

    ArrayList<Float> alPercentage = new ArrayList<Float>();
    alPercentage.add(2.0f);
    alPercentage.add(8.0f);
    alPercentage.add(20.0f);
    alPercentage.add(10.0f);
    alPercentage.add(10.0f);
    alPercentage.add(10.0f);
    alPercentage.add(10.0f);
    alPercentage.add(10.0f);
    alPercentage.add(10.85f);
    alPercentage.add(9.15f);
    try {
        // setTing data
        pie.setAdapter(alPercentagE);

        // setTing a listener
        pie.setOnSELEctedListener(new OnSELEctedLisenter() {
            @Override
            public void onSELEcted(int iSELEctedIndeX) {
                Toast.makeText(getActivity(),"SELEct index:" + iSELEctedIndex,Toast.LENGTH_SHORT).show();
            }
        });
    } catch (Exception E) {
        if (e.getmessage().equals(PieChart.ERROR_NOT_EQUAL_TO_100)) {
            Log.e("kenyang","percentage is not equal to 100");
        }
    }



public class PieChart extends View {

public interface OnSELEctedLisenter {
    public abstract void onSELEcted(int iSELEctedIndeX);
}

private OnSELEctedLisenter onSELEctedListener = null;

private static final String TAG = PieChart.class.getName();
public static final String ERROR_NOT_EQUAL_TO_100 = "NOT_EQUAL_TO_100";
private static final int DEGREE_360 = 360;
private static String[] PIE_COLORS = null;
private static int iColorListSize = 0;
ArrayList<Float> array;
private Paint paintPieFill;
private Paint paintPieBorder;
private Paint paintCenterCircle;
private ArrayList<Float> alPercentage = new ArrayList<Float>();
privatE int mCenterX = 320;
privatE int mCenterY = 320;
private int idisplayWidth,iDisplayHeight;
privatE int iSELEctedIndex = -1;
privatE int iCenterWidth = 0;
privatE int iShift = 0;
privatE int iMargin = 0; // margin to left and right,used for get Radius
private int idataSize = 0;
private Canvas canvas1;
private RectF r = null;
private RectF centerCircle = null;
private float fDensity = 0.0f;
private float fStartAngle = 0.0f;
private float fEndAngle = 0.0f;
float fX;
float fY;

public PieChart(Context context,attrs);
    PIE_COLORS = getresources().getStringArray(R.array.colors);
    iColorListSize = PIE_COLORs.length;
    array = new ArrayList<Float>();
    fnGetDisplaymetrics(context);
    iShift = (int) fnGetReaLPXFromDp(30);
    iMargin = (int) fnGetReaLPXFromDp(40);
    centerCircle = new RectF(200,200,440,440);
    // used for paint circle
    paintPieFill = new Paint(Paint.ANTI_ALIAS_FLAG);
    paintPieFill.setStyle(Paint.Style.FILL);
    // used for paint centerCircle
    paintCenterCircle = new Paint(Paint.ANTI_ALIAS_FLAG);
    paintCenterCircle.setStyle(Paint.Style.FILL);
    paintCenterCircle.setColor(Color.WHITE);
    // used for paint border
    paintPieBorder = new Paint(Paint.ANTI_ALIAS_FLAG);
    paintPieBorder.setStyle(Paint.Style.stroke);
    paintPieBorder.setstrokeWidth(fnGetReaLPXFromDp(3));
    paintPieBorder.setColor(Color.WHITE);
    Log.i(tag,"PieChart init");

}

// set listener
public void setOnSELEctedListener(OnSELEctedLisenter listener) {
    this.onSELEctedListener = listener;
}

float temp = 0;

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    Log.i(tag,"onDraw");
    float centerX = (r.left + r.right) / 2;
    float centerY = (r.top + r.bottom) / 2;
    float radius1 = (r.right - r.left) / 2;
    radius1 *= 0.5;
    float startX = mCenterX;
    float startY = mCenterY;
    float radius = mCenterX;
    float medianAngle = 0;
    Path path = new Path();

    for (int i = 0; i < iDataSize; i++) {

        // check whether the data size larger than color list size
        if (i >= iColorListSizE) {
            paintPieFill.setColor(Color.parseColor(PIE_COLORS[i
                    % iColorListSize]));
        } else {
            paintPieFill.setColor(Color.parseColor(PIE_COLORS[i]));
        }

        fEndAngle = alPercentage.get(i);

        // convert percentage to angle
        fEndAngle = fEndAngle / 100 * DEGREE_360;

        // if the part of pie was SELEcted then change the coordinate
        if (iSELEctedIndex == i) {
            canvas.save(Canvas.MATRIX_SAVE_FLAG);
            float fAngle = fStartAngle + fEndAngle / 2;
            double dxRadius = Math.toradians((fAngle + DEGREE_360)
                    % DEGREE_360);
            fY = (float) Math.sin(dxRadius);
            fX = (float) Math.cos(dxRadius);
            canvas.translate(fX * iShift,fY * iShift);
        }

        canvas.drawArc(r,fStartAngle,fEndAngle,true,paintPieFill);
        float angle = (float) ((fStartAngle + fEndAngle / 2) * Math.PI / 180);
        float stopX = (float) (startX + (radius/2) * Math.cos(anglE));
        float stopY = (float) (startY + (radius/2) * Math.sin(anglE));


        // if the part of pie was SELEcted then draw a border
        if (iSELEctedIndex == i) {
            canvas.drawArc(r,paintPieBorder);
             canvas.drawLine(startX,startY,stopX,stopY,paintPieFill);
            canvas.restore();
        }
        fStartAngle = fStartAngle + fEndAngle;
    }

}

@Override
protected void onMeasure(int widthMeasureSpec,int heightMeasureSpeC) {
    super.onMeasure(widthMeasureSpec,heightMeasureSpec);

    // get screen size
    iDisplayWidth = MeasureSpec.getSize(widthMeasureSpec);
    iDisplayHeight = MeasureSpec.getSize(heightMeasureSpec);

    if (iDisplayWidth > iDisplayHeight) {
        iDisplayWidth = iDisplayHeight;
    }

    /*
     * determine the rectangle size
     */
    iCenterWidth = iDisplayWidth / 2;
    int iR = iCenterWidth - iMargin;
    if (r == null) {
        r = new RectF(iCenterWidth - iR,// top
                iCenterWidth - iR,// left
                iCenterWidth + iR,// right
                iCenterWidth + iR); // bottom
    }
    if (centerCircle == null) {
        // centerCircle=new RectF(left,top,right,bottom);

    }
    setMeasuredDimension(iDisplayWidth,iDisplayWidth);
}

@Override
public Boolean onTouchEvent(MotionEvent event) {

    // get degree of the touch point
    double dx = Math.atan2(event.getY() - iCenterWidth,event.getX()
            - iCenterWidth);
    float fDegree = (float) (dx / (2 * Math.PI) * DEGREE_360);
    fDegree = (fDegree + DEGREE_360) % DEGREE_360;

    // get the percent of the SELEcted degree
    float fSELEctedPercent = fDegree * 100 / DEGREE_360;

    // check which pie was SELEcted
    float f@R_272_10586@lPercent = 0;
    for (int i = 0; i < iDataSize; i++) {
        f@R_272_10586@lPercent += alPercentage.get(i);
        if (f@R_272_10586@lPercent > fSELEctedPercent) {
            iSELEctedIndex = i;
            break;
        }
    }
    if (onSELEctedListener != null) {
        onSELEctedlistener.onSELEcted(iSELEctedIndeX);
    }
    invalidate();
    return super.onTouchEvent(event);
}

private void fnGetDisplaymetrics(Context cxt) {
    final Displaymetrics dm = cxt.getresources().getDisplaymetrics();
    fDensity = dm.density;
}

private float fnGetReaLPXFromDp(float fDp) {
    return (fDensity != 1.0f) ? fDensity * fDp : fDp;
}

public void setAdapter(ArrayList<Float> alPercentagE) throws Exception {
    this.alPercentage = alPercentage;
    iDataSize = alPercentage.size();
    float fSum = 0;
    for (int i = 0; i < iDataSize; i++) {
        fSum += alPercentage.get(i);
    }
    if (fSum != 100) {
        Log.e(tag,ERROR_NOT_EQUAL_TO_100);
        iDataSize = 0;
        throw new Exception(ERROR_NOT_EQUAL_TO_100);
    }

}


<com.example.piecharts.PieChart
        android:id="@+id/pieChart"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </com.example.piecharts.PieChart>

大佬总结

以上是大佬教程为你收集整理的Android甜甜圈图表全部内容,希望文章能够帮你解决Android甜甜圈图表所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。