Android: 在圆内画圆弧
Android: Drawing an arc inside a circle
我想在圆圈内画一条弧线来表示温度,但我很难做到。在搜索过程中,我找到了这些解决方案
This one I couldn't understand what is the scale method for, and is drawing more than one arch, which confused me a bit
到目前为止我达到了什么
@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:
我想拥有这样的东西
下面的自定义View
画两条弧线连接成一个圆和一个内圆。
另外,我让它填充画圆弧的矩形,View
用黄色背景,activity背景是深色的。 (这些附加功能旨在更好地了解绘制圆/弧的工作原理,它们可以帮助调试。)
自定义视图:
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);
}
}
我想在圆圈内画一条弧线来表示温度,但我很难做到。在搜索过程中,我找到了这些解决方案
This one I couldn't understand what is the scale method for, and is drawing more than one arch, which confused me a bit
到目前为止我达到了什么
@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:
我想拥有这样的东西
下面的自定义View
画两条弧线连接成一个圆和一个内圆。
另外,我让它填充画圆弧的矩形,View
用黄色背景,activity背景是深色的。 (这些附加功能旨在更好地了解绘制圆/弧的工作原理,它们可以帮助调试。)
自定义视图:
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);
}
}