Flutter如何实现Container组件的自定义角部圆角效果
Flutter Container角部切角效果实现

以下是两种可直接落地的实现方式,按需选择即可:
方案1:自定义ShapeBorder(无第三方依赖,推荐)
不需要引入任何外部包,通过自定义形状边框重绘路径即可实现,性能最好,灵活度最高。
- 先写自定义切角形状类:
import 'package:flutter/material.dart'; class NotchedCornerBorder extends ShapeBorder { final double notchSize; // 角部缺口尺寸 final Color borderColor; final double borderWidth; const NotchedCornerBorder({ this.notchSize = 12, this.borderColor = const Color(0xFFE0E0E0), this.borderWidth = 1, }); @override EdgeInsetsGeometry get dimensions => EdgeInsets.all(borderWidth); @override Path getInnerPath(Rect rect, {TextDirection? textDirection}) { return getOuterPath(rect.deflate(borderWidth), textDirection: textDirection); } @override Path getOuterPath(Rect rect, {TextDirection? textDirection}) { final path = Path(); // 绘制四个角的切角路径 path.moveTo(rect.left + notchSize, rect.top); path.lineTo(rect.right - notchSize, rect.top); path.lineTo(rect.right, rect.top + notchSize); path.lineTo(rect.right, rect.bottom - notchSize); path.lineTo(rect.right - notchSize, rect.bottom); path.lineTo(rect.left + notchSize, rect.bottom); path.lineTo(rect.left, rect.bottom - notchSize); path.lineTo(rect.left, rect.top + notchSize); path.close(); return path; } @override void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) { if (borderWidth <= 0) return; final paint = Paint() ..color = borderColor ..strokeWidth = borderWidth ..style = PaintingStyle.stroke; canvas.drawPath(getOuterPath(rect), paint); } @override ShapeBorder scale(double t) { return NotchedCornerBorder( notchSize: notchSize * t, borderColor: borderColor, borderWidth: borderWidth * t, ); } }
- 直接在Container中使用:
Container( width: 240, height: 120, alignment: Alignment.center, decoration: ShapeDecoration( color: Colors.white, // 配置阴影效果 shadows: const [ BoxShadow( color: Colors.black12, blurRadius: 4, offset: Offset(0, 2), ) ], shape: NotchedCornerBorder( notchSize: 18, // 调整这个值匹配设计图的缺口大小 borderColor: Colors.blue, borderWidth: 2, ), ), child: const Text("切角容器内容"), )
如果需要实现内凹圆角而非直切角,只要把getOuterPath里的直线绘制方法lineTo替换为quadraticBezierTo绘制圆弧路径即可;如果只需要单个/部分角做切角,对应删减路径绘制逻辑就行。
方案2:第三方包快速实现
不想手动绘制路径的话,可以直接用封装好的组件快速实现:
- 在
pubspec.yaml中添加依赖:
dependencies: shape_of_view_null_safe: ^2.0.1
- 引入后直接使用:
ShapeOfView( shape: CutCornerShape(18), // 18为切角尺寸 borderColor: Colors.blue, borderWidth: 2, child: Container( width: 240, height: 120, color: Colors.white, alignment: Alignment.center, child: const Text("第三方实现切角容器"), ), )
调试技巧
- 调整
notchSize/切角尺寸参数,直到和参考图的角部比例完全一致 - 如果容器内有点击事件,自定义Shape的方案会自动适配点击区域,不会出现边角空白区域也响应点击的问题
内容的提问来源于stack exchange,提问作者YsfKcr
相关产品推荐
相关产品推荐

