Flutter:如何实现仅边角带边框的Container自定义形状
Flutter实现Container仅四个边角带边框效果
你可以通过自定义CustomPaint绘制或者Stack堆叠边角装饰两种方式实现需求,以下是两种方案的具体实现:
方案1:自定义CustomPainter实现(推荐,灵活性高)
该方案可以自由调整边框粗细、边角长度、圆角大小、颜色等参数,适配性更强。
完整代码示例:
import 'package:flutter/material.dart'; class CornerBorderPainter extends CustomPainter { // 可自定义参数 final Color borderColor; final double borderWidth; final double cornerLength; // 每个边角的边框长度 final double borderRadius; CornerBorderPainter({ required this.borderColor, required this.borderWidth, required this.cornerLength, required this.borderRadius, }); @override void paint(Canvas canvas, Size size) { final paint = Paint() ..color = borderColor ..style = PaintingStyle.stroke ..strokeWidth = borderWidth; final r = Radius.circular(borderRadius); // 左上角 Path topLeftPath = Path() ..moveTo(0, cornerLength + borderRadius.x) ..lineTo(0, borderRadius.y) ..arcToPoint(Offset(borderRadius.x, 0), radius: r) ..lineTo(cornerLength + borderRadius.x, 0); canvas.drawPath(topLeftPath, paint); // 右上角 Path topRightPath = Path() ..moveTo(size.width - cornerLength - borderRadius.x, 0) ..lineTo(size.width - borderRadius.x, 0) ..arcToPoint(Offset(size.width, borderRadius.y), radius: r) ..lineTo(size.width, cornerLength + borderRadius.y); canvas.drawPath(topRightPath, paint); // 右下角 Path bottomRightPath = Path() ..moveTo(size.width, size.height - cornerLength - borderRadius.y) ..lineTo(size.width, size.height - borderRadius.y) ..arcToPoint(Offset(size.width - borderRadius.x, size.height), radius: r) ..lineTo(size.width - cornerLength - borderRadius.x, size.height); canvas.drawPath(bottomRightPath, paint); // 左下角 Path bottomLeftPath = Path() ..moveTo(cornerLength + borderRadius.x, size.height) ..lineTo(borderRadius.x, size.height) ..arcToPoint(Offset(0, size.height - borderRadius.y), radius: r) ..lineTo(0, size.height - cornerLength - borderRadius.y); canvas.drawPath(bottomLeftPath, paint); } @override bool shouldRepaint(covariant CustomPainter oldDelegate) => false; } // 使用示例 class CornerBorderContainer extends StatelessWidget { const CornerBorderContainer({super.key}); @override Widget build(BuildContext context) { return CustomPaint( painter: CornerBorderPainter( borderColor: Colors.white, borderWidth: 2, cornerLength: 20, // 可调整边角边框的长度 borderRadius: 18, ), child: Container( width: 200, height: 100, decoration: BoxDecoration( color: Colors.red, borderRadius: BorderRadius.circular(18), ), child: const Center( child: Text( 'Monday', style: TextStyle( color: Colors.white, fontSize: 30, ), ), ), ), ); } }
方案2:Stack堆叠实现(代码简单)
如果不想自定义绘制,可以直接在Stack里放四个边角的小装饰容器,适合快速实现:
class StackCornerBorderContainer extends StatelessWidget { const StackCornerBorderContainer({super.key}); @override Widget build(BuildContext context) { const borderWidth = 2.0; const cornerLength = 20.0; const borderRadius = 18.0; return Stack( children: [ // 底层主体Container Container( width: 200, height: 100, decoration: BoxDecoration( color: Colors.red, borderRadius: BorderRadius.circular(borderRadius), ), child: const Center( child: Text( 'Monday', style: TextStyle( color: Colors.white, fontSize: 30, ), ), ), ), // 左上角装饰 Positioned( top: 0, left: 0, child: Container( width: cornerLength + borderRadius, height: cornerLength + borderRadius, decoration: BoxDecoration( borderRadius: const BorderRadius.only(topLeft: Radius.circular(borderRadius)), border: Border( top: BorderSide(color: Colors.white, width: borderWidth), left: BorderSide(color: Colors.white, width: borderWidth), ), ), ), ), // 右上角装饰 Positioned( top: 0, right: 0, child: Container( width: cornerLength + borderRadius, height: cornerLength + borderRadius, decoration: BoxDecoration( borderRadius: const BorderRadius.only(topRight: Radius.circular(borderRadius)), border: Border( top: BorderSide(color: Colors.white, width: borderWidth), right: BorderSide(color: Colors.white, width: borderWidth), ), ), ), ), // 右下角装饰 Positioned( bottom: 0, right: 0, child: Container( width: cornerLength + borderRadius, height: cornerLength + borderRadius, decoration: BoxDecoration( borderRadius: const BorderRadius.only(bottomRight: Radius.circular(borderRadius)), border: Border( bottom: BorderSide(color: Colors.white, width: borderWidth), right: BorderSide(color: Colors.white, width: borderWidth), ), ), ), ), // 左下角装饰 Positioned( bottom: 0, left: 0, child: Container( width: cornerLength + borderRadius, height: cornerLength + borderRadius, decoration: BoxDecoration( borderRadius: const BorderRadius.only(bottomLeft: Radius.circular(borderRadius)), border: Border( bottom: BorderSide(color: Colors.white, width: borderWidth), left: BorderSide(color: Colors.white, width: borderWidth), ), ), ), ), ], ); } }
两种方案都可以实现你要的四个边角带边框的效果,根据自己的开发需求选择即可。
内容的提问来源于stack exchange,提问作者Millenial2020
相关产品推荐
相关产品推荐

