如何在Flutter中为Container组件实现自定义样式边框?
Flutter实现二维码分段式拐角边框方案
你当前使用的Border.all只能生成完整实心边框,无法实现图中的仅四个拐角显示的分段效果,可通过以下两种方案实现:
方案1:Stack叠加实现(最简单,无需自定义绘制)
思路是在二维码外层用Stack,底部放二维码主体,顶层四个角分别放置仅显示相邻两条边的小尺寸Container,代码示例如下:
Stack( alignment: Alignment.center, children: [ // 底层二维码主体 Padding( padding: EdgeInsets.all(15.sp), child: QrImage( data: controller.generatedCode, version: QrVersions.auto, size: 300.0, ), ), // 左上角拐角 Positioned( left: 0, top: 0, child: Container( height: 40, width: 40, decoration: BoxDecoration( border: Border( top: BorderSide(color: kPrimaryColor, width: 7), left: BorderSide(color: kPrimaryColor, width: 7), ), ), ), ), // 右上角拐角 Positioned( right: 0, top: 0, child: Container( height: 40, width: 40, decoration: BoxDecoration( border: Border( top: BorderSide(color: kPrimaryColor, width: 7), right: BorderSide(color: kPrimaryColor, width: 7), ), ), ), ), // 左下角拐角 Positioned( left: 0, bottom: 0, child: Container( height: 40, width: 40, decoration: BoxDecoration( border: Border( bottom: BorderSide(color: kPrimaryColor, width: 7), left: BorderSide(color: kPrimaryColor, width: 7), ), ), ), ), // 右下角拐角 Positioned( right: 0, bottom: 0, child: Container( height: 40, width: 40, decoration: BoxDecoration( border: Border( bottom: BorderSide(color: kPrimaryColor, width: 7), right: BorderSide(color: kPrimaryColor, width: 7), ), ), ), ), ], )
你可以自行调整拐角Container的宽高、边框宽度、颜色来匹配设计需求。
方案2:自定义CustomPainter绘制(性能更高,适合封装复用)
如果需要频繁使用该样式,推荐自定义绘制组件,减少嵌套层级,代码示例如下:
首先定义自定义绘制类:
class QrCornerPainter extends CustomPainter { final Color color; final double strokeWidth; final double cornerLength; // 拐角每条边的长度 QrCornerPainter({ required this.color, required this.strokeWidth, required this.cornerLength, }); @override void paint(Canvas canvas, Size size) { final paint = Paint() ..color = color ..strokeWidth = strokeWidth ..style = PaintingStyle.stroke; // 左上角 canvas.drawLine(Offset(0, 0), Offset(cornerLength, 0), paint); canvas.drawLine(Offset(0, 0), Offset(0, cornerLength), paint); // 右上角 canvas.drawLine(Offset(size.width, 0), Offset(size.width - cornerLength, 0), paint); canvas.drawLine(Offset(size.width, 0), Offset(size.width, cornerLength), paint); // 左下角 canvas.drawLine(Offset(0, size.height), Offset(cornerLength, size.height), paint); canvas.drawLine(Offset(0, size.height), Offset(0, size.height - cornerLength), paint); // 右下角 canvas.drawLine(Offset(size.width, size.height), Offset(size.width - cornerLength, size.height), paint); canvas.drawLine(Offset(size.width, size.height), Offset(size.width, size.height - cornerLength), paint); } @override bool shouldRepaint(covariant QrCornerPainter oldDelegate) { return color != oldDelegate.color || strokeWidth != oldDelegate.strokeWidth || cornerLength != oldDelegate.cornerLength; } }
使用时直接包裹二维码即可:
CustomPaint( painter: QrCornerPainter( color: kPrimaryColor, strokeWidth: 7, cornerLength: 40, ), child: Padding( padding: EdgeInsets.all(15.sp), child: QrImage( data: controller.generatedCode, version: QrVersions.auto, size: 300.0, ), ), )
内容的提问来源于stack exchange,提问作者Visage98
相关产品推荐
相关产品推荐

