Android:在圆圈内绘制圆弧

时间:2016-08-29 12:47:28

标签: android android-canvas android-custom-view ondraw

我试图在圆圈内画一个圆弧来表示温度,但我很难实现这个目标。在我搜索期间,我找到了那些解决方案

This one I couldn't understand what is the scale method for, and is drawing more than one arch, which confused me a bit

This post gave it a fixed size where I need the size to be controlled by the custom view in my XML layout

From here I understood the concept the degrees but I didn't understand how to determine the oval size

到目前为止我得到了什么

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

    int startTop = 0;
    int startLeft = 0;
    int endBottom = getHeight() / 2;
    int endRight = endBottom;// This makes an equal square.

    int centerX = getWidth() / 2;
    int centerY = getHeight() / 2;

    int upperEdgeX = (int) (centerX + getWidth() / 2 * Math.cos(270 * Math.PI / 180));
    int upperEdgeY = (int) (centerY + getWidth() / 2 * Math.sin(270 * Math.PI / 180));

    int bottomEdgeX = (int) (centerX + getWidth() / 2 * Math.cos(90 * Math.PI / 180));
    int bottomEdgeY = (int) (centerY + getWidth() / 2 * Math.sin(90 * Math.PI / 180));

    int leftEdgeX = (int) (centerX + getWidth() / 2 * Math.cos(180 * Math.PI / 180));
    int leftEdgeY = (int) (centerY + getWidth() / 2 * Math.sin(180 * Math.PI / 180));

    int rightEdgeX = (int) (centerX + getWidth() / 2 * Math.cos(0 * Math.PI / 180));
    int rightEdgeY = (int) (centerY + getWidth() / 2 * Math.sin(0 * Math.PI / 180));

    RectF rect = new RectF(startTop, startLeft, endRight, endBottom);
    canvas.drawCircle(centerX, centerY, getWidth() / 2, mBasePaint);


    canvas.drawCircle(centerX, centerY, getWidth() / 3, mCenterPaint); // White circle
}

更新 我需要我的观点就像一个甜甜圈饼图,中间将持有学位

更新2:

我想尝试这样的事情

enter image description here

1 个答案:

答案 0 :(得分:8)

以下自定义View绘制两个连接的圆弧,以形成圆形和内圆。

enter image description here

此外,我让它填充用于绘制弧的矩形,并使用黄色背景作为public class MySimpleView extends View{ private static final int STROKE_WIDTH = 20; private Paint mBasePaint, mDegreesPaint, mCenterPaint, mRectPaint; private RectF mRect; private int centerX, centerY, radius; public MySimpleView(Context context) { super(context); init(); } public MySimpleView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public MySimpleView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { mRectPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mRectPaint.setColor(ContextCompat.getColor(getContext(), R.color.magenta)); mRectPaint.setStyle(Paint.Style.FILL); mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mCenterPaint.setColor(ContextCompat.getColor(getContext(), R.color.white)); mCenterPaint.setStyle(Paint.Style.FILL); mBasePaint = new Paint(Paint.ANTI_ALIAS_FLAG); mBasePaint.setStyle(Paint.Style.STROKE); mBasePaint.setStrokeWidth(STROKE_WIDTH); mBasePaint.setColor(ContextCompat.getColor(getContext(), R.color.blue)); mDegreesPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mDegreesPaint.setStyle(Paint.Style.STROKE); mDegreesPaint.setStrokeWidth(STROKE_WIDTH); mDegreesPaint.setColor(ContextCompat.getColor(getContext(), R.color.green)); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // getHeight() is not reliable, use getMeasuredHeight() on first run: // Note: mRect will also be null after a configuration change, // so in this case the new measured height and width values will be used: if (mRect == null) { // take the minimum of width and height here to be on he safe side: centerX = getMeasuredWidth()/ 2; centerY = getMeasuredHeight()/ 2; radius = Math.min(centerX,centerY); // mRect will define the drawing space for drawArc() // We have to take into account the STROKE_WIDTH with drawArc() as well as drawCircle(): // circles as well as arcs are drawn 50% outside of the bounds defined by the radius (radius for arcs is calculated from the rectangle mRect). // So if mRect is too large, the lines will not fit into the View int startTop = STROKE_WIDTH / 2; int startLeft = startTop; int endBottom = 2 * radius - startTop; int endRight = endBottom; mRect = new RectF(startTop, startLeft, endRight, endBottom); } // just to show the rectangle bounds: canvas.drawRect(mRect, mRectPaint); // subtract half the stroke width from radius so the blue circle fits inside the View canvas.drawCircle(centerX, centerY, radius - STROKE_WIDTH / 2, mBasePaint); // Or draw arc from degree 192 to degree 90 like this ( 258 = (360 - 192) + 90: // canvas.drawArc(mRect, 192, 258, false, mBasePaint); // draw an arc from 90 degrees to 192 degrees (102 = 192 - 90) // Note that these degrees are not like mathematical degrees: // they are mirrored along the y-axis and so incremented clockwise (zero degrees is always on the right hand side of the x-axis) canvas.drawArc(mRect, 90, 102, false, mDegreesPaint); // subtract stroke width from radius so the white circle does not cover the blue circle/ arc canvas.drawCircle(centerX, centerY, radius - STROKE_WIDTH, mCenterPaint); } } ,活动背景是暗的。 (这些附加功能旨在更好地了解绘制圆/弧的工作原理,它们可以帮助调试。)

自定义视图:

host/gitweb?p=somepath&a=summary