自定义视图 - 由线条绘制的圆角矩形的角

custom view - rounding rectangle's corners drawn by lines

我正在玩自定义视图,我想使用 path.lineTo()path.arcTo() 方法构建一个圆角矩形。
所以,我想要得到的矩形:

通常我用这段代码画这个:

    RectF backReftf = new RectF();
    Path path = new Path();
    int width = getWidth();
    int height = getHeight();
    float curve = (float) (0.1 *  height);
    RectF backReftf = new RectF();
    backReftf.left = 0;
    backReftf.top = 0;
    backReftf.right = width;
    backReftf.bottom = height;
    path.addRoundRect(backReftf, curve, curve, Path.Direction.CW);
    canvas.drawPath(path, paint);

但我想用 path.lineTo()path.arcTo() 画这个。

根据关于 arcTo() 的文档:

Append the specified arc to the path as a new contour. If the start of the path is different from the path's current last point, then an automatic lineTo() is added to connect the current contour to the start of the arc. However, if the path is empty, then we call moveTo() with the first point of the arc.

所以理论上我的弧线应该从那里开始,线结束的地方,所以如果我画一条线(矩形的左侧):

    float curve = (float) (0.1 *  height);
    path.moveTo(0,0);
    path.lineTo(0, height - curve);

那么我的弧线应该从这个点开始(0,高度 - 曲线),但是当 arcTo() 有以下参数时我应该把这些参数传递到哪里:arcTo (float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean forceMoveTo)

加上在这种情况下如何计算 startAnglesweepAngle

提前致谢!

绘制圆弧时,您需要指定该圆弧的完整边界框,以及起始角和扫描角。我试着在视觉上看到它们,就像这样:

例如顺时针方向时,起始角位于距原点 180 度的位置。从 startAngle 开始,如果顺时针旋转 90 度,您将到达所需的结束位置。

注意原点、startAngle 和 sweepAngle 在此图形中的位置。 在科特林中,它看起来像这样:

// Given some radius, viewWidth and viewHeight
override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        path.apply {
            moveTo(radius, 0F)
            lineTo(viewWidth - radius, 0F)
            arcTo(viewWidth - 2 * radius, 0F, viewWidth, 2 * radius, -90F, 90F, false)
            lineTo(viewWidth, radius)
            arcTo(viewWidth - 2 * radius, viewHeight - 2 * radius, viewWidth, viewHeight, 0F, 90F, false)
            lineTo(radius, viewHeight)
            arcTo(0F, viewHeight - 2 * radius, 2 * radius, viewHeight, 90F, 90F, false)
            lineTo(0F, radius)
            arcTo(0F, 0F, 2 * radius, 2 * radius, 180F, 90F, false)
        }

        canvas?.drawPath(path, linePaint)
    }

结果将是这样的: