QinGang_interested/lib/customWidget/IconBadgeButton.dart

113 lines
3.6 KiB
Dart
Raw Permalink Normal View History

2025-12-12 09:11:30 +08:00
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,
),
),
),
],
),
),
);
}
}