如何用Flutter CustomPainter实现带圆角与阴影的三角组件
Flutter:实现带圆角和阴影的三角形组件优化需求
目标效果

当前实现效果

我尝试通过CustomPainter绘制三角形,并结合Stack添加阴影,但结果未达预期,以下是现有代码:
左侧三角形代码
import 'package:custom_widget_component/core/widgets/button_shadow/model_color/card_color_model.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; class LeftTriangle extends StatelessWidget { final Widget child; final double radius; final CardColorModel color; const LeftTriangle({ super.key, required this.child, this.radius = 2, required this.color, }); @override Widget build(BuildContext context) { return LayoutBuilder( builder: (context, constraints) { return Stack( children: [ CustomPaint( painter: _RoundedTrianglePainter(color: color.shadow, radius: radius), child: Container( padding: EdgeInsets.only( top: 10.h, right: 14.w, left: 10.w, bottom: 14.h, ), child: const Text(' '), ), ), CustomPaint( painter: _RoundedTrianglePainter( color: color.card, radius: radius, ), child: Container( padding: EdgeInsets.only( left: 9.w, right: 8.w, top: 12.h, bottom: 8.h, ), child: child, ), ), ], ); }, ); } } class _RoundedTrianglePainter extends CustomPainter { final double radius; final Color color; _RoundedTrianglePainter({required this.color, required this.radius}); @override void paint(Canvas canvas, Size size) { final Paint paint = Paint() ..color = color ..style = PaintingStyle.fill; final Path path = Path(); // 左侧弧形起始 path.moveTo(0 + radius, size.height / 2 - radius); path.quadraticBezierTo( 0, size.height / 2, 0 + radius, size.height / 2 + radius, ); // 右下角圆角 path.lineTo(size.width - radius, size.height); path.quadraticBezierTo( size.width, size.height, size.width, size.height - radius, ); // 右上角圆角 path.lineTo(size.width, radius); path.quadraticBezierTo( size.width, 0, size.width - radius, 0, ); path.close(); canvas.drawPath(path, paint); } @override bool shouldRepaint(covariant CustomPainter oldDelegate) => false; }
右侧三角形代码
import 'package:custom_widget_component/core/widgets/button_shadow/model_color/card_color_model.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; class RightTriangle extends StatelessWidget { final Widget child; final double radius; final CardColorModel color; const RightTriangle( {super.key, required this.child, this.radius = 4, required this.color}); @override Widget build(BuildContext context) { return LayoutBuilder( builder: (context, constraints) { return Stack( children: [ CustomPaint( painter: _RoundedTrianglePainter(color: color.shadow, radius: radius), child: Container( padding: EdgeInsets.only( top: 10.h, right: 14.w, left: 10.w, bottom: 14.h, ), child: const Text(' '), ), ), CustomPaint( painter: _RoundedTrianglePainter( color: color.card, radius: radius, ), child: Container( padding: EdgeInsets.only( left: 9.w, right: 8.w, top: 12.h, bottom: 8.h, ), child: child, ), ), ], ); }, ); } } class _RoundedTrianglePainter extends CustomPainter { final double radius; final Color color; _RoundedTrianglePainter({required this.color, this.radius = 2}); @override void paint(Canvas canvas, Size size) { final Paint paint = Paint() ..color = color ..style = PaintingStyle.fill; final Path path = Path(); // 左上角圆角 path.moveTo(radius, 0); path.quadraticBezierTo( 0, 0, 0, radius, ); // 左下角圆角 path.lineTo(0, size.height - radius); path.quadraticBezierTo( 0, size.height, radius, size.height, ); // 右侧弧形 path.lineTo(size.width - radius, size.height / 2 + radius); path.quadraticBezierTo( size.width, size.height / 2, size.width - radius, size.height / 2 - radius, ); path.close(); canvas.drawPath(path, paint); } @override bool shouldRepaint(covariant CustomPainter oldDelegate) => false; }
组件使用示例
LeftTriangle( color: Colors.green, child: Text( "number", style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, ), ), ),
具体问题
- 圆角处理:三角形的圆角未按设计要求正确呈现
- 阴影效果:阴影与三角形融合度差,视觉效果不自然
- 整体形状:最终绘制的三角形形状与设计目标不符
请帮忙优化代码,解决上述问题,实现符合设计要求的带圆角和阴影的三角形组件。
内容的提问来源于stack exchange,提问作者Ifqy Gifha azhar
相关产品推荐
相关产品推荐

