自定义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
相关产品推荐
相关产品推荐

