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

自定义View绘制两个TextView间的连线无法正常显示问题求助

问题根因与修复方案

你遇到的问题主要由三个配置遗漏/错误导致:

  • 未给画笔设置描边宽度,默认Paint的strokeWidth为0,线条极细很难观察到
  • 自定义DrawLineView未设置正确的布局尺寸,默认wrap_content下视图宽高为0/极小,超出视图范围的绘制内容会被系统裁剪,这也是你只能看到竖线的核心原因:横向的连线超出了DrawLineView的可用绘制区域
  • 直接使用getX()/getY()获取的是视图相对于自身父布局的坐标,没有做坐标转换,在多层布局下坐标偏移会导致绘制位置错误

修复后的代码示例

1. 自定义DrawLineView修改

public class DrawLineView extends View {
    private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private final View startView;
    private final View endView;

    public DrawLineView(Context context, View startView, View endView) {
        super(context);
        this.startView = startView;
        this.endView = endView;
        // 初始化画笔配置
        paint.setColor(Color.BLACK);
        paint.setStrokeWidth(4f); // 设置合理的线宽
        paint.setStyle(Paint.Style.STROKE);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // 让DrawLineView撑满父布局,获得完整的绘制区域
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (startView == null || endView == null) return;
        
        // 统一转换为窗口坐标,再偏移为当前DrawLineView的相对坐标,避免多层布局的坐标偏移问题
        int[] startPos = new int[2];
        startView.getLocationInWindow(startPos);
        int[] endPos = new int[2];
        endView.getLocationInWindow(endPos);
        int[] myPos = new int[2];
        getLocationInWindow(myPos);

        // 计算连线起止点,默认对齐TextView的垂直水平中点,可自行调整偏移量
        float startX = startPos[0] + startView.getWidth() / 2f - myPos[0];
        float startY = startPos[1] + startView.getHeight() / 2f - myPos[1];
        float endX = endPos[0] + endView.getWidth() / 2f - myPos[0];
        float endY = endPos[1] + endView.getHeight() / 2f - myPos[1];

        canvas.drawLine(startX, startY, endX, endY, paint);
    }
}

2. 调用逻辑修改

if (selectedTag1 == selectedTag2) {
    drawLineView = new DrawLineView(MatchingContentScreen.this, selectedTextFromColumn1, selectedTextFromColumn2);
    // 给DrawLineView设置match_parent的布局参数,撑满父RelativeLayout
    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
        ViewGroup.LayoutParams.MATCH_PARENT,
        ViewGroup.LayoutParams.MATCH_PARENT
    );
    drawLineView.setLayoutParams(params);
    relativeLayout.addView(drawLineView);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 22:54:03