Flutter中实现Workflow Builder UI:容器连线方案咨询
Flutter 实现工作流容器连线的方案
一、自定义绘制(最灵活)
核心用CustomPainter实现容器间的连线,步骤如下:
- 记录容器位置:给每个工作流容器绑定
GlobalKey,通过key.currentContext?.findRenderObject()获取容器的全局坐标与尺寸,计算出连线的起点(比如容器右侧中点)和终点(下一个容器左侧中点)。 - 绘制连线:自定义
CustomPainter类,在paint方法里用Canvas.drawLine绘制基础连线,若需要箭头,用Path绘制三角形箭头形状。 - 叠加绘制层:用
Stack布局,把容器放在下层,自定义绘制层放在上层,确保连线不会被容器遮挡。
示例代码片段:
// 获取容器右侧中点的全局坐标 Offset getContainerRightMid(GlobalKey key) { final renderBox = key.currentContext?.findRenderObject() as RenderBox?; if (renderBox == null) return Offset.zero; final pos = renderBox.localToGlobal(Offset.zero); final size = renderBox.size; return Offset(pos.dx + size.width, pos.dy + size.height / 2); } // 自定义连线绘制器 class ConnectionPainter extends CustomPainter { final List<Offset> linePoints; final Color lineColor; final double lineWidth; ConnectionPainter({ required this.linePoints, this.lineColor = Colors.blue, this.lineWidth = 2, }); @override void paint(Canvas canvas, Size size) { final paint = Paint() ..color = lineColor ..strokeWidth = lineWidth ..style = PaintingStyle.stroke; // 绘制直线 if (linePoints.length >= 2) { canvas.drawLine(linePoints[0], linePoints[1], paint); // 绘制箭头 _drawArrow(canvas, linePoints[0], linePoints[1], paint); } } void _drawArrow(Canvas canvas, Offset start, Offset end, Paint paint) { const arrowSize = 10.0; final direction = end - start; final unitDir = direction.normalized; final perpendicular = Offset(-unitDir.dy, unitDir.dx); final arrowTip1 = end - unitDir * arrowSize + perpendicular * arrowSize / 2; final arrowTip2 = end - unitDir * arrowSize - perpendicular * arrowSize / 2; final arrowPath = Path() ..moveTo(end.dx, end.dy) ..lineTo(arrowTip1.dx, arrowTip1.dy) ..lineTo(arrowTip2.dx, arrowTip2.dy) ..close(); canvas.drawPath(arrowPath, paint); } @override bool shouldRepaint(covariant ConnectionPainter oldDelegate) { return oldDelegate.linePoints != linePoints; } } // 页面布局示例 Stack( children: [ // 工作流容器1 Positioned( left: 50, top: 50, child: Container( key: containerKey1, width: 150, height: 80, color: Colors.grey[200], child: const Center(child: Text("步骤1")), ), ), // 工作流容器2 Positioned( left: 300, top: 50, child: Container( key: containerKey2, width: 150, height: 80, color: Colors.grey[200], child: const Center(child: Text("步骤2")), ), ), // 连线绘制层 CustomPaint( painter: ConnectionPainter( linePoints: [ getContainerRightMid(containerKey1), getContainerRightMid(containerKey2), ], ), size: MediaQuery.of(context).size, ), ], )
二、使用轻量流程图库
如果不想从零开发,可直接使用flutter_flow_chart这类专门的流程图库,它支持容器拖拽、自动连线、自定义样式,能快速搭建类似工作流界面。
三、处理动态交互
若需要支持拖拽容器后自动更新连线,可给容器套GestureDetector处理拖拽事件,实时更新Positioned的位置参数,并在setState中刷新连线的坐标,触发CustomPainter重绘。
内容的提问来源于stack exchange,提问作者Isy
相关产品推荐
相关产品推荐

