我在自定义视图中在画布上绘制一个圆弧,如下所示。 Paint
和rectangle
是在onDraw()
之外定义的,并且为了简单起见而添加到其中。
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
RectF rectangle = new RectF(60f, 60f, 480f, 480f);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(0x40000000);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(120);
canvas.drawArc(rectangle, 225f, 315f, false, paint);
}
当我使用4.3在Galaxy Nexus上运行此代码时,会出现以下人为因素。
在使用4.4.4的Nexus 5上运行时没有这样的假象。
我通过像(225f,315f)这样的角度和其他一些角度来观察这些假象。大多数情况下,弧形的形状是正确的。
有没有办法避免那些人工制品?
更新:我尝试使用setLayerType()
使用软件,硬件和无图层。人工制品改变了形式,但仍然存在。
答案 0 :(得分:2)
我是StackOverflow新手,想添加评论但不能(分数不足),所以不得不把我的评论放在答案中!
奇怪的是,电弧超出了指定的终点位置,外侧有一条直的垂直线。内端点似乎没问题。当然,这个和其他乱七八糟的线条并没有说明导致问题的原因。
当结束角度精确 90度的倍数时,似乎会出现。这看起来像一个数字计算错误,浮动圆整问题等。@ kcoppock评论说314.98f已经绕过了这个bug。可能除了315.0f以外的任何值都可能有效。
如果涉及代码优化(尝试以尽可能小的线段绘制弧),可能有效的另一个技巧是通过将弧切成碎片来简化弧 - >使用多个drawArc调用,每个调用跨越一定的最大角度。考生分别为30度,45度,90度和180度。如果关节不可见,仍然有待观察......
这有点远,希望这些建议都可行。
答案 1 :(得分:0)
我找到了解决方案! :)
而不是:
RectF rectangle = new RectF(60f, 60f, 480f, 480f);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(0x40000000);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(120);
canvas.drawArc(rectangle, 225f, 315f, false, paint);
使用此:
RectF rectangle = new RectF(60f, 60f, 480f, 480f);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(0x40000000);
paint.setStyle(Paint.Style.FILL);
float strokeWidth = 120;
float startAngle = 225f;
float sweepAngle = 315f;
RectF pathRect = new RectF();
Path path = new Path();
float s = strokeWidth / 2;
pathRect.left = rectangle.left - s;
pathRect.right = rectangle.right + s;
pathRect.top = rectangle.top - s;
pathRect.bottom = rectangle.bottom + s;
path.arcTo(pathRect, startAngle, sweepAngle);
pathRect.left = rectangle.left + s;
pathRect.right = rectangle.right - s;
pathRect.top = rectangle.top + s;
pathRect.bottom = rectangle.bottom - s;
path.arcTo(pathRect, startAngle + sweepAngle, -sweepAngle);
path.close();
canvas.drawPath(path, paint);
此代码导致运行速度较慢,但它不会产生伪影。 :)