Flutter教程:如何实现带圆角的自定义下划线Tab指示器
Flutter 为 UnderlineTabIndicator 添加圆角的解决方案
UnderlineTabIndicator 本身确实没有内置 borderRadius 属性,要实现带圆角的Tab下划线,最可靠的方式是自定义一个继承自 Decoration 的Tab指示器,通过Canvas精准绘制带圆角的底部线条。
自定义圆角下划线指示器
先创建一个自定义的 RoundedUnderlineTabIndicator 类:
class RoundedUnderlineTabIndicator extends Decoration { final BorderSide borderSide; final EdgeInsetsGeometry insets; final BorderRadius borderRadius; const RoundedUnderlineTabIndicator({ this.borderSide = const BorderSide(width: 2.0, color: Colors.blue), this.insets = EdgeInsets.zero, this.borderRadius = const BorderRadius.all(Radius.circular(4.0)), }); @override BoxPainter createBoxPainter([VoidCallback? onChanged]) { return _RoundedUnderlinePainter(this, onChanged); } } class _RoundedUnderlinePainter extends BoxPainter { final RoundedUnderlineTabIndicator decoration; _RoundedUnderlinePainter(this.decoration, VoidCallback? onChanged) : super(onChanged); @override void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) { final Rect rect = offset & configuration.size; final EdgeInsets insets = decoration.insets.resolve(configuration.textDirection); final Rect indicatorRect = insets.deflateRect(rect); // 定位下划线:贴住Tab底部,高度等于borderSide的宽度 final Paint paint = decoration.borderSide.toPaint() ..style = PaintingStyle.fill; final Rect underlineRect = Rect.fromLTWH( indicatorRect.left, indicatorRect.bottom - decoration.borderSide.width, indicatorRect.width, decoration.borderSide.width, ); // 绘制仅顶部带圆角的矩形(底部圆角无需显示) canvas.drawRRect( RRect.fromRectAndCorners( underlineRect, topLeft: decoration.borderRadius.topLeft, topRight: decoration.borderRadius.topRight, bottomLeft: Radius.zero, bottomRight: Radius.zero, ), paint, ); } }
在你的TabBar中替换使用
把原本的 UnderlineTabIndicator 替换成自定义的指示器,并设置需要的圆角参数:
TabBar( controller: _tabController, labelStyle: TextStyle(fontWeight: FontWeight.w600, fontSize: 16), unselectedLabelColor: Colors.black, labelColor: Colors.black, indicatorSize: TabBarIndicatorSize.tab, // 使用自定义圆角指示器 indicator: RoundedUnderlineTabIndicator( borderSide: BorderSide( width: 5.0, color: HexColor("2C7381"), ), insets: EdgeInsets.symmetric(horizontal: 10.0, vertical: 0), borderRadius: BorderRadius.circular(5.0), // 自定义圆角大小 ), tabs: [ Container( color: Colors.amber, child: Padding( padding: const EdgeInsets.only(bottom: 10), child: Column( children: [ Image.asset( _activeIndex == 0 ? "assets/icons/dummy1.png" : "assets/icons/dummy2.png", height: 20, ), SizedBox(height: 5), Text( "TAB 0", style: Dummytheme.text14theme, textAlign: TextAlign.center, ), ], ), ), ), // 其他Tab项... ], )
原方案失效的原因
ShapeDecoration 是基于Tab的整体尺寸进行绘制的,无法精准定位到底部的小范围区域;而自定义Painter可以直接控制绘制的位置、形状,完美适配Tab底部下划线的圆角需求。
内容的提问来源于stack exchange,提问作者Alifa Al Farizi
相关产品推荐
相关产品推荐

