如何在 Android 中使用画布旋转文本

发布于 2024-11-02 13:05:57 字数 360 浏览 8 评论 0原文

我正在 Android 中使用 canvas 绘制饼图。我正在使用下面的代码。我在该饼图的每个切片上绘制文本(在路径上绘制圆弧),现在我想按长度绘制文本,即从每个切片的中心到末端,那么如何使用起始角度和扫描角度旋转圆弧。

p.addArc(mEventsRect, fStartAngle, fSweepAngle);
mBgPaints.setColor(iTextColor);
canvas.drawTextOnPath(sTextValue, p, fHOffSet, fVOffSet, mBgPaints);

在此处输入图像描述

I was drawing a pie chart using canvas in Android. I am using the below code. I draw a text on each slice of that pie chart (draw arc on path), now I want to draw the text length wise i.e. from center to end of the each slice, so how to rotate the arc using start and sweep angle.

p.addArc(mEventsRect, fStartAngle, fSweepAngle);
mBgPaints.setColor(iTextColor);
canvas.drawTextOnPath(sTextValue, p, fHOffSet, fVOffSet, mBgPaints);

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

飞烟轻若梦 2024-11-09 13:05:57

您可以尝试以下代码片段:(来自: http://www.helloandroid .com/tutorials/how-use-canvas-your-android-apps-part-2

int x = 75;
int y = 185;
paint.setColor(Color.GRAY);
paint.setTextSize(25);
String rotatedtext = "Rotated helloandroid :)";

//Draw bounding rect before rotating text:

Rect rect = new Rect();
paint.getTextBounds(rotatedtext, 0, rotatedtext.length(), rect);
canvas.translate(x, y);
paint.setStyle(Paint.Style.FILL);

canvas.drawText(rotatedtext , 0, 0, paint);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRect(rect, paint);

canvas.translate(-x, -y);


paint.setColor(Color.RED);
canvas.rotate(-45, x + rect.exactCenterX(),y + rect.exactCenterY());
paint.setStyle(Paint.Style.FILL);
canvas.drawText(rotatedtext, x, y, paint);

You can try this snippet: (from: http://www.helloandroid.com/tutorials/how-use-canvas-your-android-apps-part-2)

int x = 75;
int y = 185;
paint.setColor(Color.GRAY);
paint.setTextSize(25);
String rotatedtext = "Rotated helloandroid :)";

//Draw bounding rect before rotating text:

Rect rect = new Rect();
paint.getTextBounds(rotatedtext, 0, rotatedtext.length(), rect);
canvas.translate(x, y);
paint.setStyle(Paint.Style.FILL);

canvas.drawText(rotatedtext , 0, 0, paint);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRect(rect, paint);

canvas.translate(-x, -y);


paint.setColor(Color.RED);
canvas.rotate(-45, x + rect.exactCenterX(),y + rect.exactCenterY());
paint.setStyle(Paint.Style.FILL);
canvas.drawText(rotatedtext, x, y, paint);
静谧 2024-11-09 13:05:57

您已经有了文本的 x 和 y,使用它们来旋转画布。

canvas.rotate(yourDegrees, x, y)
canvas.drawText(yourText, x, y, yourPaint)
canvas.rotate(-yourDegrees, x, y)

负号否定第一次旋转。您可以交换它以沿相反方向旋转。

您可以在循环中执行此操作,但每次坐标更改时都必须完成旋转循环。

You'll already have the x and y for your text, use these to rotate the canvas

canvas.rotate(yourDegrees, x, y)
canvas.drawText(yourText, x, y, yourPaint)
canvas.rotate(-yourDegrees, x, y)

The negative sign negates the first rotation. You could swap it around to rotate in the opposite direction.

You could do this in a loop but the rotation cycle must be done each time either coordinate changes.

離殇 2024-11-09 13:05:57

也许这会对你有所帮助,,
这里39.5是半径,这将在mdpi屏幕上完美显示结果

 protected void onDraw(){
        canvas.save();
    PointF pf = PointOnCircle(35f, 45f, new PointF(39.5f, 39.5f));
            canvas.rotate(-45, pf.x, pf.y);
            canvas.drawText("67%", pf.x, pf.y, red);//23.5
            canvas.restore();
            canvas.save();
            PointF pfa = PointOnCircle(35f, 135f, new PointF(39.5f, 39.5f));
            canvas.rotate(45, pfa.x, pfa.y);
            canvas.drawText("33%", pfa.x, pfa.y, red);//23.5
            canvas.restore();
            canvas.save();
            pfa = PointOnCircle(27.5f, 225f, new PointF(39.5f, 39.5f));
            canvas.rotate(-45, pfa.x, pfa.y);
            canvas.drawText("45%", pfa.x, pfa.y, red);//23.5
            canvas.restore();
            canvas.save();
            pfa = PointOnCircle(27.5f, 315f, new PointF(39.5f, 39.5f));
            canvas.rotate(45, pfa.x, pfa.y);
            canvas.drawText("55%", pfa.x, pfa.y, red);//23.5

            canvas.restore();}

    protected static final PointF PointOnCircle(float radius, float angleInDegrees, PointF origin) {
            // Convert from degrees to radians via multiplication by PI/180        
            float x = (float) (radius * Math.cos(angleInDegrees * Math.PI / 180F)) + origin.x;
            float y = (float) (radius * Math.sin(angleInDegrees * Math.PI / 180F)) + origin.y;

            return new PointF(x, y);
        }

may be this will help you,,
here 39.5 is radius,, this will perfectly show result on mdpi screen

 protected void onDraw(){
        canvas.save();
    PointF pf = PointOnCircle(35f, 45f, new PointF(39.5f, 39.5f));
            canvas.rotate(-45, pf.x, pf.y);
            canvas.drawText("67%", pf.x, pf.y, red);//23.5
            canvas.restore();
            canvas.save();
            PointF pfa = PointOnCircle(35f, 135f, new PointF(39.5f, 39.5f));
            canvas.rotate(45, pfa.x, pfa.y);
            canvas.drawText("33%", pfa.x, pfa.y, red);//23.5
            canvas.restore();
            canvas.save();
            pfa = PointOnCircle(27.5f, 225f, new PointF(39.5f, 39.5f));
            canvas.rotate(-45, pfa.x, pfa.y);
            canvas.drawText("45%", pfa.x, pfa.y, red);//23.5
            canvas.restore();
            canvas.save();
            pfa = PointOnCircle(27.5f, 315f, new PointF(39.5f, 39.5f));
            canvas.rotate(45, pfa.x, pfa.y);
            canvas.drawText("55%", pfa.x, pfa.y, red);//23.5

            canvas.restore();}

    protected static final PointF PointOnCircle(float radius, float angleInDegrees, PointF origin) {
            // Convert from degrees to radians via multiplication by PI/180        
            float x = (float) (radius * Math.cos(angleInDegrees * Math.PI / 180F)) + origin.x;
            float y = (float) (radius * Math.sin(angleInDegrees * Math.PI / 180F)) + origin.y;

            return new PointF(x, y);
        }
扛刀软妹 2024-11-09 13:05:57

这是我在这个库的帮助下经过两天的搜索后终于做到的 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, AttributeSet attrs) {
        super(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, fStartAngle, fEndAngle, true, 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 fTotalPercent = 0;
        for (int i = 0; i < iDataSize; i++) {
            fTotalPercent += alPercentage.get(i);
            if (fTotalPercent > 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>

Here's how i finally did it after two days of search with help of this library https://github.com/Ken-Yang/AndroidPieChart
And equations to center text done with help of my friends and alot of search

on MainActivity onCreate or oncreateView if you are using fragments:

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, AttributeSet attrs) {
        super(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, fStartAngle, fEndAngle, true, 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 fTotalPercent = 0;
        for (int i = 0; i < iDataSize; i++) {
            fTotalPercent += alPercentage.get(i);
            if (fTotalPercent > 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);
        }

    }

in your Layout:

<com.example.piecharts.PieChart
        android:id="@+id/pieChart"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </com.example.piecharts.PieChart>
揽月 2024-11-09 13:05:57

这个问题很老了,但我想我应该写一个一般性的答案。在这里,我假设您想在画布中间绘制饼图,并且您在数组中拥有起始角度和渗透角度。

x = canvas.getWidth/2 //Horizontal center of canvas view
y = canvas.getHeight/2 //Vertical center of canvas view
canvas.rotate(fStartAngle[i]+ fSweepAngle[i]/2, x ,y ); //Rotates canvas to a line in the middle 
//of start and end of arc
canvas.translate(50f,0);//Moves the text a little out of the center of the circle (50f is arbitrary)
paintText.setStyle(Paint.Style.FILL);
canvas.drawText(rotatedtext, x, y, paintText);
//Undo the translations and rotations so that next arc can be drawn normally
canvas.translate(-50f,0); 
canvas.rotate(-(temp+ value_degree[i]/2), x ,y );

This question is pretty old, but I figured I would write a general answer.Here I assume you want to draw your pie chart in the middle of the canvas and that you have your start and seep angles in an array.

x = canvas.getWidth/2 //Horizontal center of canvas view
y = canvas.getHeight/2 //Vertical center of canvas view
canvas.rotate(fStartAngle[i]+ fSweepAngle[i]/2, x ,y ); //Rotates canvas to a line in the middle 
//of start and end of arc
canvas.translate(50f,0);//Moves the text a little out of the center of the circle (50f is arbitrary)
paintText.setStyle(Paint.Style.FILL);
canvas.drawText(rotatedtext, x, y, paintText);
//Undo the translations and rotations so that next arc can be drawn normally
canvas.translate(-50f,0); 
canvas.rotate(-(temp+ value_degree[i]/2), x ,y );
遇到 2024-11-09 13:05:57

现在是 2023 年,可能还有其他答案,但这里有一个肯定有效的答案

    //the path where your text/paint will be drawn across
    Path path = new Path();

    path.addArc(mEventsRect, fStartAngle, fSweepAngle);//add this if you want your path to be drawn across the arc of your sector

    //if you are using a text get the width
    float textWidth = mTextPaint.measureText("text");

    //this is the y co-ordinate your text will start from
    int hOffset = 100;

    //this is the x co-ordinate your text will start from
    int vOffset = 100;

    //we will be using the matrix to rotate the bunds of our current path
    Matrix matrix = new Matrix();

    //we will use this to get the bounds of our current path
    RectF bounds = new RectF();

    path.computeBounds(bounds,true);

    //we are using the matrix to rotate the bound (with is the bound of the path) by 90 degrees
    matrix.setRotate(90,bounds.centerX(),bounds.centerY());

    the we transform the points in the path using the matrix
    path.transform(matrix);

    //you can now draw the text on the path
    canvas.drawTextOnPath("text", path, hOffset, vOffset , mBgPaints);

it's 2023 there might be other answers out there but here is one that is sure to work

    //the path where your text/paint will be drawn across
    Path path = new Path();

    path.addArc(mEventsRect, fStartAngle, fSweepAngle);//add this if you want your path to be drawn across the arc of your sector

    //if you are using a text get the width
    float textWidth = mTextPaint.measureText("text");

    //this is the y co-ordinate your text will start from
    int hOffset = 100;

    //this is the x co-ordinate your text will start from
    int vOffset = 100;

    //we will be using the matrix to rotate the bunds of our current path
    Matrix matrix = new Matrix();

    //we will use this to get the bounds of our current path
    RectF bounds = new RectF();

    path.computeBounds(bounds,true);

    //we are using the matrix to rotate the bound (with is the bound of the path) by 90 degrees
    matrix.setRotate(90,bounds.centerX(),bounds.centerY());

    the we transform the points in the path using the matrix
    path.transform(matrix);

    //you can now draw the text on the path
    canvas.drawTextOnPath("text", path, hOffset, vOffset , mBgPaints);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文