Flutter自定义Snackbar:如何同时实现圆角与底部彩色边框
解决方案
要实现带圆角且仅底部有彩色边框的Snackbar,由于默认的RoundedRectangleBorder无法单独设置单一边框样式,我们可以自定义一个ShapeBorder来满足需求,无需依赖外部库或嵌套Container。
1. 自定义圆角底部边框类
创建一个继承自ShapeBorder的类,实现圆角和底部边框的绘制逻辑:
import 'dart:math'; import 'package:flutter/material.dart'; class RoundedBottomBorder extends ShapeBorder { final BorderRadius borderRadius; final BorderSide bottomSide; const RoundedBottomBorder({ this.borderRadius = const BorderRadius.all(Radius.circular(8)), this.bottomSide = const BorderSide(color: Colors.green, width: 4), }); @override EdgeInsetsGeometry get dimensions => EdgeInsets.only(bottom: bottomSide.width); @override Path getInnerPath(Rect rect, {TextDirection? textDirection}) { return Path() ..addRRect(borderRadius.resolve(textDirection).toRRect(rect).deflate(bottomSide.width)); } @override Path getOuterPath(Rect rect, {TextDirection? textDirection}) { return Path()..addRRect(borderRadius.resolve(textDirection).toRRect(rect)); } @override void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) { final paint = bottomSide.toPaint(); final rRect = borderRadius.resolve(textDirection).toRRect(rect); // 绘制底部直线边框 final start = Offset(rRect.left, rRect.bottom - rRect.bottomLeftRadius.y); final end = Offset(rRect.right, rRect.bottom - rRect.bottomRightRadius.y); canvas.drawLine(start, end, paint); // 绘制左下角圆角边框 canvas.drawArc( Rect.fromLTWH(rRect.left, rRect.bottom - rRect.bottomLeftRadius.y * 2, rRect.bottomLeftRadius.x * 2, rRect.bottomLeftRadius.y * 2), 0, pi / 2, false, paint, ); // 绘制右下角圆角边框 canvas.drawArc( Rect.fromLTWH(rRect.right - rRect.bottomRightRadius.x * 2, rRect.bottom - rRect.bottomRightRadius.y * 2, rRect.bottomRightRadius.x * 2, rRect.bottomRightRadius.y * 2), -pi / 2, pi / 2, false, paint, ); } @override ShapeBorder scale(double t) { return RoundedBottomBorder( borderRadius: borderRadius * t, bottomSide: bottomSide.scale(t), ); } }
2. 在Snackbar中使用自定义边框
直接将自定义的RoundedBottomBorder赋值给Snackbar的shape参数即可:
var snackBar = SnackBar( behavior: SnackBarBehavior.floating, backgroundColor: Colors.white, // 可根据需求修改背景色 shape: const RoundedBottomBorder( borderRadius: BorderRadius.all(Radius.circular(8)), bottomSide: BorderSide(color: Colors.green, width: 4), ), content: Flex( direction: Axis.horizontal, children: [ Padding( padding: const EdgeInsets.only(right: 12), child: Icon(Icons.add), ), Text("Toast message"), ], ), );
这个自定义边框通过绘制底部直线和左右圆角弧,同时保证Snackbar的内容区域是圆角的,完美结合了你需要的两个效果。
内容的提问来源于stack exchange,提问作者Ana
相关产品推荐
相关产品推荐

