我试图在android视图中画一个180°的弧。
在我使用的onDraw方法中,如下所示:

canvas.drawArc(arcRect, 180.0f, 180.0f, false, arcBackgroundPaint);

正在使用的油漆具有Canvas::drawArc类型的strokeCap。如下图所示,弧的末端看起来不太正确。端部从内径到外径略微向上倾斜。
android - 为什么Canvas::drawArc方法绘制不正确的角度?-LMLPHP
有人知道为什么会这样吗?除了更改传递给DrawArc的值以使其实际绘制超过180度之外,是否有其他方法来修复它?这似乎是一个我宁愿避免的讨厌的黑客。
更新:
根据要求,我添加了在弧底部画一条直线的代码。我在画弧线之前画这条线,所以这条线在后面。我也做了黑色的弧线,以获得更好的对比线。结果如下:
android - 为什么Canvas::drawArc方法绘制不正确的角度?-LMLPHP
讨厌.
这里有一个与反走样关闭的线和弧…
android - 为什么Canvas::drawArc方法绘制不正确的角度?-LMLPHP

最佳答案

如果硬件加速打开,将出现Drawarc角度错误问题。
使用Real Phone(Nexus 5,Android 6.0.1)复制。
如何测试:
android:hardwareAccelerated="false"添加到androidmanifest.xml中的应用程序标记。
NB:
在文档中找不到DrawArc()的第一个受支持的API级别,但其缩放函数来自API17。
硬件加速>画布缩放
https://developer.android.com/guide/topics/graphics/hardware-accel.html
第一个支持的API级别
简单形状:17
注意:“简单”形状有DrawRect()、DrawCircle()、DrawOval()、DrawRoundRect()和DrawArc()(useCenter=false)。
更新:
正如picyourbain在另一个答案中所说,drawArc()是这个问题发生的部分原因。
对于drawPath(),不会出现此问题。
供参考:
不同形状但usecenter=true的drawArc()似乎也可以安全使用,因为它不使用硬件加速。(弧的两端和弧的中心与直线相连,直线看起来很直。)
画布缩放(上面的链接相同)
第一个支持的API级别
复杂形状:X
其他与drawArc()
Canvas.drawArc() artefacts
What's this weird drawArc() / arcTo() bug (graphics glitch) in Android?
[旧]
我把这些留给你参考。
这是我试过的一些测试结果。
更新1-1:
使用Emulator Nexus5 API10和arcRect = new RectF(100, 100, 1500, 1400);
android - 为什么Canvas::drawArc方法绘制不正确的角度?-LMLPHP
对于Emulator Nexus5 API16,这种情况不会发生。
(区别在于(主机侧)硬件加速的存在。)
我认为这似乎是一个与反别名相关的问题,但无论是否设置了arcBackgroundPaint.setAntiAlias(true)setDither(true),都会发生这种情况。
注:这是打字错误造成的,对不起。对于此测试,ArcRect的纵横比应为1:1。
使用arcRect = new RectF(100, 100, 1400, 1400);arcPenWidth = 200f;
android - 为什么Canvas::drawArc方法绘制不正确的角度?-LMLPHP
arcRect = new RectF(100, 100, 1500, 1300);
android - 为什么Canvas::drawArc方法绘制不正确的角度?-LMLPHP
1-2:用于比较
带Emulator NexusOne(480x800,HDPI)API10,带arcRect = new RectF(100, 100, 500, 500);
android - 为什么Canvas::drawArc方法绘制不正确的角度?-LMLPHP
更新2:线路延长。
我首先认为从视图外绘制可能会导致这种情况,但这也是一个模拟器错误。(不是特定于drawarc()的行为。)
当模拟器API10处于横向(水平)方向时,会发生这种情况。
线路位置的计算似乎中断了。
请看直线的右端。

final float lineStartX = arcRect.left - 250f;
final float lineEndX = arcRect.right + 250f;

仿真器Nexus5 API10
android - 为什么Canvas::drawArc方法绘制不正确的角度?-LMLPHP
水平(API10)
android - 为什么Canvas::drawArc方法绘制不正确的角度?-LMLPHP
垂直(API10)
android - 为什么Canvas::drawArc方法绘制不正确的角度?-LMLPHP
2-2:仅供参考
视图位置(或绘图位置)的奇数行为示例超出范围。
android - 为什么Canvas::drawArc方法绘制不正确的角度?-LMLPHP
android - 为什么Canvas::drawArc方法绘制不正确的角度?-LMLPHP
更新3:模拟器错误
请看图片的底部。
蓝线是桌面的背景图像。
仿真器Nexus5 API10
android - 为什么Canvas::drawArc方法绘制不正确的角度?-LMLPHP
更新4:结果似乎取决于风格。
带标题栏
android - 为什么Canvas::drawArc方法绘制不正确的角度?-LMLPHP
不带标题栏
android - 为什么Canvas::drawArc方法绘制不正确的角度?-LMLPHP
更新5:结果似乎取决于行宽。
ArcPenWidth=430F(API10,水平)
右侧有轻微凹痕。
android - 为什么Canvas::drawArc方法绘制不正确的角度?-LMLPHP
带锁
android - 为什么Canvas::drawArc方法绘制不正确的角度?-LMLPHP
450F
android - 为什么Canvas::drawArc方法绘制不正确的角度?-LMLPHP
这是我的(第一个)测试代码。
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

final class TestView extends View
{
    RectF arcRect;
    Paint arcBackgroundPaint;
    Paint linePaint;

    public TestView(final Context context, final AttributeSet attrs)
    {
        super(context, attrs);
        //arcRect = new RectF(100, 100, 500, 500);
        arcRect = new RectF(100, 100, 1500, 1500); // fixed (old: 1500, 1400)
        arcBackgroundPaint = new Paint();
        arcBackgroundPaint.setColor(0xFFFFFFFF);
        arcBackgroundPaint.setStyle(Paint.Style.STROKE);
        arcBackgroundPaint.setStrokeCap(Paint.Cap.BUTT);
        arcBackgroundPaint.setStrokeWidth(200f);
        linePaint = new Paint();
        linePaint.setColor(0xFF00FF00);
        linePaint.setStyle(Paint.Style.STROKE);
        linePaint.setStrokeCap(Paint.Cap.BUTT);
        linePaint.setStrokeWidth(2f);
    }

    @Override
    protected void onDraw(final Canvas canvas)
    {
        super.onDraw(canvas);
        canvas.drawArc(arcRect, 180.0f, 180.0f, false, arcBackgroundPaint);
        final float lineStartX = arcRect.left - 50f;
        final float lineEndX = arcRect.right + 50f;
        final float lineY = arcRect.centerY();
        canvas.drawLine(lineStartX, lineY, lineEndX, lineY, linePaint);
    }
}

关于android - 为什么Canvas::drawArc方法绘制不正确的角度?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47268665/

10-10 00:18