import 'package:flutter/material.dart'; /// 网格布局组件 class WorkTabIconGrid extends StatelessWidget { final List> buttonInfos; final ValueChanged onItemPressed; final double leftSpace; const WorkTabIconGrid({ super.key, required this.buttonInfos, required this.onItemPressed, this.leftSpace = 0, }); @override Widget build(BuildContext context) { final double screenW = MediaQuery.of(context).size.width; final double itemW = (screenW - 2 * leftSpace) / 4; return Container( padding: EdgeInsets.symmetric(vertical: 10, horizontal: leftSpace), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8), ), child: buttonInfos.length <= 4 ? Row( mainAxisAlignment: MainAxisAlignment.start, children: buttonInfos.asMap().entries.map((entry) { final index = entry.key; final info = entry.value; return _buildIconButton( context: context, iconPath: info['icon'] as String, label: info['title'] as String, unreadCount: int.tryParse(info['unreadCount'].toString()) ?? 0, onPressed: () => onItemPressed(index), width: itemW, ); }).toList(), ) : Wrap( spacing: 0, runSpacing: 16, alignment: WrapAlignment.start, children: buttonInfos.asMap().entries.map((entry) { final index = entry.key; final info = entry.value; return _buildIconButton( context: context, iconPath: info['icon'] as String, label: info['title'] as String, unreadCount: info['unreadCount'] is String ? int.tryParse(info['unreadCount']) : info['unreadCount'] is int ? info['unreadCount'] : 0, onPressed: () => onItemPressed(index), width: itemW, ); }).toList(), ), ); } Widget _buildIconButton({ required BuildContext context, required String iconPath, required String label, required VoidCallback onPressed, required double width, int unreadCount = 0, }) { return InkWell( onTap: onPressed, borderRadius: BorderRadius.circular(8), child: SizedBox( width: width, child: Stack( clipBehavior: Clip.none, children: [ Align( alignment: Alignment.topCenter, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ Image.asset(iconPath, width: 30, height: 30), const SizedBox(height: 5), Text( label, style: const TextStyle(fontSize: 13), textAlign: TextAlign.center, ), ], ), ), if (unreadCount > 0) Positioned( right: width / 4 - 10, top: -5, child: Container( padding: const EdgeInsets.symmetric( horizontal: 4, vertical: 2, ), decoration: BoxDecoration( color: Colors.red, borderRadius: BorderRadius.circular(10), ), constraints: const BoxConstraints( minWidth: 16, minHeight: 16, ), child: Center( child: Text( unreadCount > 999 ? '999+' : '$unreadCount', style: const TextStyle( color: Colors.white, fontSize: 10, height: 1, ), textAlign: TextAlign.center, ), ), ), ), ], ), ), ); } }