如何在Flutter中用Canvas绘制带圆角的水平菱形(Rhombus)
为Flutter菱形组件添加圆角的实现方案
要实现带圆角的菱形,确实需要通过Path的arcToPoint方法手动绘制每个角的圆弧——RRect无法直接适配菱形的斜向边角。以下是基于你现有代码完善后的实现:
import 'package:flutter/material.dart'; /// Diamond Widget class Diamond extends StatelessWidget { /// Constructor const Diamond({ required this.width, required this.height, this.lineColor = Colors.black, this.cornerRadius = 8.0, super.key, }); /// Width of the diamond final double width; /// Height of the diamond final double height; /// Outline's color of the diamond final Color lineColor; /// Corner radius of the diamond final double cornerRadius; @override Widget build(BuildContext context) { return CustomPaint( size: Size(width, height), painter: _DiamondPainter( lineColor: lineColor, cornerRadius: cornerRadius, ), ); } } /// Custom painter for drawing a diamond class _DiamondPainter extends CustomPainter { _DiamondPainter({required this.lineColor, required this.cornerRadius}); final Color lineColor; final double cornerRadius; @override void paint(Canvas canvas, Size size) { final Paint paint = Paint() ..style = PaintingStyle.stroke ..color = lineColor ..strokeWidth = 2.0 ..strokeJoin = StrokeJoin.round; // 优化线条衔接处的平滑度 // 限制圆角最大值,避免超过菱形可容纳的范围导致变形 final double safeRadius = min( cornerRadius, min(size.width / 4, size.height / 4), ); final halfWidth = size.width / 2; final halfHeight = size.height / 2; final Path path = Path() // 顶部圆角:从右侧端点开始 ..moveTo(halfWidth + safeRadius, 0) // 绘制顶部内凹圆弧到左侧端点 ..arcToPoint( Offset(halfWidth - safeRadius, 0), radius: Radius.circular(safeRadius), clockwise: false, ) // 绘制左侧边到左侧圆角的上端点 ..lineTo(0, halfHeight - safeRadius) // 绘制左侧内凹圆弧到左侧圆角的下端点 ..arcToPoint( Offset(0, halfHeight + safeRadius), radius: Radius.circular(safeRadius), clockwise: false, ) // 绘制底部边到底部圆角的左端点 ..lineTo(halfWidth - safeRadius, size.height) // 绘制底部内凹圆弧到底部圆角的右端点 ..arcToPoint( Offset(halfWidth + safeRadius, size.height), radius: Radius.circular(safeRadius), clockwise: false, ) // 绘制右侧边到右侧圆角的下端点 ..lineTo(size.width, halfHeight + safeRadius) // 绘制右侧内凹圆弧到右侧圆角的上端点 ..arcToPoint( Offset(size.width, halfHeight - safeRadius), radius: Radius.circular(safeRadius), clockwise: false, ) // 闭合路径 ..close(); canvas.drawPath(path, paint); } @override bool shouldRepaint(covariant _DiamondPainter oldDelegate) { return lineColor != oldDelegate.lineColor || cornerRadius != oldDelegate.cornerRadius; } }
核心细节说明
- 安全圆角限制:通过
safeRadius把圆角半径控制在菱形宽度/4、高度/4的最小值以内,避免圆角过大导致图形结构异常。 - 圆弧绘制逻辑:每个圆角都遵循「移动到圆弧端点→绘制内凹圆弧→连接下一段直线」的流程,
clockwise: false确保圆弧向菱形内部弯曲。 - 线条衔接优化:添加
strokeJoin: StrokeJoin.round,让线条与圆弧的衔接处更平滑,消除尖锐棱角。 - 重绘逻辑优化:修改
shouldRepaint方法,仅当颜色或圆角参数变化时触发重绘,提升性能。
内容的提问来源于stack exchange,提问作者Hamed Heydarian
相关产品推荐
相关产品推荐

