import 'package:flutter/material.dart'; class IconBadgeButton extends StatelessWidget { final String iconPath; final String title; final int unreadCount; final VoidCallback onTap; final double width; // 可选:按钮宽度(默认 80) const IconBadgeButton({ Key? key, required this.iconPath, required this.title, required this.onTap, this.unreadCount = 0, this.width = 80, }) : super(key: key); @override Widget build(BuildContext context) { // badge 文本,超过 99 展示 99+ final String badgeText = unreadCount.toString(); // 文字两行的高度估算(可按需微调) const double titleLineHeight = 18.0; const double titleMaxLines = 2; final double titleHeight = titleLineHeight * titleMaxLines + 2; // +2 兜底 padding return GestureDetector( behavior: HitTestBehavior.opaque, onTap: onTap, child: SizedBox( width: width, child: Column( mainAxisSize: MainAxisSize.min, children: [ // 图标 + 角标(固定高度容器) SizedBox( width: 50, height: 50, child: Stack( clipBehavior: Clip.none, children: [ // 圆形背景图标(始终居中) Container( width: 50, height: 50, decoration: BoxDecoration( color: const Color(0xFFE8F4FD), borderRadius: BorderRadius.circular(25), ), child: Center( child: Image.asset( iconPath, width: 30, height: 30, fit: BoxFit.contain, ), ), ), // 角标(只有 unreadCount > 0 时显示) if (unreadCount > 0) Positioned( top: -6, right: -6, child: Container( padding: const EdgeInsets.symmetric(horizontal: 5), constraints: const BoxConstraints(minWidth: 18, minHeight: 18), decoration: BoxDecoration( color: Colors.red, borderRadius: BorderRadius.circular(9), border: Border.all(color: Colors.white, width: 1.5), ), alignment: Alignment.center, child: Text( badgeText, style: const TextStyle( color: Colors.white, fontSize: 10, fontWeight: FontWeight.bold, ), textAlign: TextAlign.center, ), ), ), ], ), ), // 固定高度的文字区域(最多两行),保持图标位置不变 SizedBox( height: titleHeight, child: Center( child: Text( title, style: const TextStyle( fontSize: 12, color: Colors.black87, ), textAlign: TextAlign.center, maxLines: 2, overflow: TextOverflow.ellipsis, ), ), ), ], ), ), ); } }