// 共享空状态组件 — 统一所有页面的空数据展示 // // 使用: EmptyStateWidget(icon: Icons.xxx, title: '暂无数据', subtitle: '下拉刷新试试') // 样式参考: home_page._EmptyJournalState — 大图标淡化 + 标题 + 副标题 + 暖色按钮 import 'package:flutter/material.dart'; import '../core/constants/design_tokens.dart'; import '../core/theme/app_colors.dart'; import '../core/theme/app_radius.dart'; /// 统一空状态组件 — 图标 + 标题 + 可选副标题 + 可选操作按钮 class EmptyStateWidget extends StatelessWidget { const EmptyStateWidget({ super.key, required this.icon, required this.title, this.subtitle, this.actionLabel, this.onAction, this.iconSize = 64, }); /// 主图标 final IconData icon; /// 图标大小 final double iconSize; /// 标题文字 final String title; /// 副标题(灰色小字) final String? subtitle; /// 操作按钮文字(不传则不显示按钮) final String? actionLabel; /// 操作按钮回调 final VoidCallback? onAction; @override Widget build(BuildContext context) { final theme = Theme.of(context); return Center( child: Padding( padding: const EdgeInsets.symmetric(vertical: DesignTokens.spacing40), child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon( icon, size: iconSize, color: theme.colorScheme.onSurface.withValues(alpha: 0.2), ), const SizedBox(height: DesignTokens.spacing16), Text( title, style: theme.textTheme.bodyLarge?.copyWith( color: theme.colorScheme.onSurfaceVariant, ), textAlign: TextAlign.center, ), if (subtitle != null) ...[ const SizedBox(height: DesignTokens.spacing8), Text( subtitle!, style: theme.textTheme.bodyMedium?.copyWith( color: theme.colorScheme.onSurfaceVariant.withValues(alpha: 0.6), ), textAlign: TextAlign.center, ), ], if (actionLabel != null && onAction != null) ...[ const SizedBox(height: DesignTokens.spacing24), FilledButton.icon( onPressed: onAction, icon: const Icon(Icons.add_rounded), label: Text(actionLabel!), style: FilledButton.styleFrom( backgroundColor: AppColors.accent, foregroundColor: AppColors.bgLight, shape: RoundedRectangleBorder( borderRadius: AppRadius.pillBorder, ), padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), ), ), ], ], ), ), ); } }