You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Canvas绘制贝塞尔连接线条时如何去除连接处的多余线段?

修复方案

核心问题原因

  1. 控件中心点计算错误:Y轴中心错误使用了控件宽度getWidth()计算,控件非正方形时端点错位,出现多余线条痕迹
  2. Paint样式配置错误:若Paint使用填充模式,Path会自动生成闭合边,表现为多余连线
  3. 分段绘制Path:多次调用drawPath绘制单段曲线,衔接处笔触叠加会产生多余痕迹

修改步骤

  1. 修正Paint配置,确保仅描边模式,配置好抗锯齿和衔接样式(Paint初始化放在构造方法中,不要重复创建)
// 在自定义View的构造方法中调用该方法初始化Paint
private void initPaint() {
    mPaint = new Paint();
    mPaint.setStyle(Paint.Style.STROKE); // 核心配置:仅描边,禁用填充
    mPaint.setStrokeWidth(5f); // 可自行调整线宽
    mPaint.setAntiAlias(true); // 开启抗锯齿
    mPaint.setStrokeJoin(Paint.Join.ROUND); // 线条衔接处用圆角,避免生硬缺口
    mPaint.setColor(Color.RED); // 可自行调整线条颜色
}
  1. 修复中心点计算逻辑,Y轴中心使用控件高度getHeight()计算
private Point[] initPoint() {
    Point[] points = new Point[6];
    int[] location1 = {(int) mOneView.getX(), (int) mOneView.getY()};
    int[] location2 = {(int) mTwoView.getX(), (int) mTwoView.getY()};
    int[] location3 = {(int) mThreeView.getX(), (int) mThreeView.getY()};
    int[] location4 = {(int) mFourView.getX(), (int) mFourView.getY()};
    int[] location5 = {(int) mFiveView.getX(), (int) mFiveView.getY()};
    int[] location6 = {(int) mSixView.getX(), (int) mSixView.getY()};
    
    // 修复Y轴中心点计算错误,替换getWidth()为getHeight()
    points[0] = new Point(location1[0] + mOneView.getWidth() / 2, location1[1] + mOneView.getHeight() / 2);
    points[1] = new Point(location2[0] + mTwoView.getWidth() / 2, location2[1] + mTwoView.getHeight() / 2);
    points[2] = new Point(location3[0] + mThreeView.getWidth() / 2, location3[1] + mThreeView.getHeight() / 2);
    points[3] = new Point(location4[0] + mFourView.getWidth() / 2, location4[1] + mFourView.getHeight() / 2);
    points[4] = new Point(location5[0] + mFiveView.getWidth() / 2, location5[1] + mFiveView.getHeight() / 2);
    points[5] = new Point(location6[0] + mSixView.getWidth() / 2, location6[1] + mSixView.getHeight() / 2);
    return points;
}
  1. 优化Path绘制逻辑,所有曲线加入同一个Path后统一绘制
protected void dispatchDraw(Canvas canvas) {
    super.dispatchDraw(canvas);
    Point[] points = initPoint();
    Path path = new Path();
    // 定位到起始点
    path.moveTo(points[0].x, points[0].y);
    for (int i = 0; i < points.length - 1; i++) {
        Point startp = points[i];
        Point endp = points[i + 1];
        int wt = (startp.x + endp.x) / 2;
        Point p3 = new Point(wt, startp.y);
        Point p4 = new Point(wt, endp.y);
        path.cubicTo(p3.x, p3.y, p4.x, p4.y, endp.x, endp.y);
    }
    // 统一绘制全段路径,仅调用一次drawPath
    canvas.drawPath(path, mPaint);
}

可选兼容方案

如果以上修改后仍存在多余线段,可在自定义View构造方法中添加以下代码关闭硬件加速即可:

setLayerType(LAYER_TYPE_SOFTWARE, null);

内容的提问来源于stack exchange,提问作者user7916816

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 23:27:02