QinGang_interested/lib/customWidget/work_tab_icon_grid.dart

140 lines
4.6 KiB
Dart

import 'package:flutter/material.dart';
/// 网格布局组件
class WorkTabIconGrid extends StatelessWidget {
final List<Map<String, dynamic>> buttonInfos;
final ValueChanged<int> 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,
),
),
),
),
],
),
),
);
}
}