QinGang_interested/lib/customWidget/IconBadgeButton.dart

113 lines
3.6 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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,
),
),
),
],
),
),
);
}
}