import 'package:flutter/material.dart'; import '../../constants/app_constants.dart'; import 'tags/corr_page.dart'; /// 时间: 2026-04-01 /// 功能: 分类页面 /// 介绍: 展示诗词分类,包括场景分类和朝代分类 /// 最新变化: 重新设计iOS风格布局,减少间距,加大字体,显示分类数量 class CategoryPage extends StatefulWidget { const CategoryPage({super.key}); @override State createState() => _CategoryPageState(); } class _CategoryPageState extends State with SingleTickerProviderStateMixin { late TabController _tabController; final List> _tabCategories = [ {'label': '场景分类', 'icon': Icons.category}, {'label': '朝代分类', 'icon': Icons.history}, ]; static const sceneData = { "节日": ["七夕节", "中秋节", "元宵节", "寒食节", "清明节", "端午节", "重阳节", "春节", "节日"], "季节": ["三月", "二月", "冬天", "夏天", "春天", "春季", "秋天"], "古籍": [ "三国志", "三国演义", "三字经", "中庸", "列子", "史记", "后汉书", "吕氏春秋", "商君书", "围炉夜话", "增广贤文", "墨子", "孙子兵法", "孟子", "小窗幽记", "尚书", "左传", "幼学琼林", "庄子", "战国策", "文心雕龙", "易传", "晋书", "汉书", "淮南子", "礼记", "管子", "红楼梦", "老子", "荀子", "菜根谭", "警世通言", "论语", "资治通鉴", "韩非子", "鬼谷子", "古籍", "格言联璧", ], "情感": ["伤感", "励志", "友情", "思乡", "思念", "感恩", "爱国", "爱情", "离别"], "景物": ["庐山", "泰山", "西湖", "长江", "黄河", "边塞", "田园", "山水", "夜景"], "天文气象": ["写云", "写雨", "写雪", "写风", "星星", "月亮", "流星"], "动植物": ["写鸟", "柳树", "桃花", "梅花", "竹子", "荷花", "菊花"], "语言文学": ["对联", "谚语", "一言", "读书", "哲理"], "其他": ["母亲", "老师", "户外", "礼物", "酒"], }; static const dynastyData = { "主要朝代": ["唐代", "宋代", "元代", "明代", "清代"], "古代朝代": ["南北朝", "五代", "隋代"], "近现代": ["近现代", "用户投稿", "管理员测试"], "其他": ["暂无朝代"], }; @override void initState() { super.initState(); _tabController = TabController(length: _tabCategories.length, vsync: this); } @override void dispose() { _tabController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Column( children: [ // Tab栏 Container( color: Colors.white, padding: const EdgeInsets.symmetric(horizontal: 16), child: TabBar( controller: _tabController, tabs: _tabCategories .map( (category) => Tab( child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon(category['icon'], size: 18), const SizedBox(width: 6), Text(category['label']), ], ), ), ) .toList(), labelColor: AppConstants.primaryColor, unselectedLabelColor: Colors.grey[600], indicatorColor: AppConstants.primaryColor, indicatorWeight: 3, labelStyle: const TextStyle( fontWeight: FontWeight.w600, fontSize: 16, ), unselectedLabelStyle: const TextStyle( fontWeight: FontWeight.normal, fontSize: 16, ), ), ), Container(height: 0.5, color: const Color(0xFFE5E5EA)), // 内容区域 Expanded( child: Container( color: const Color(0xFFF2F2F7), child: TabBarView( controller: _tabController, children: [ _buildCategoryList(sceneData, _tabCategories[0]['label']), _buildCategoryList(dynastyData, _tabCategories[1]['label']), ], ), ), ), ], ); } Widget _buildCategoryList( Map> data, String categoryType, ) { return ListView.separated( padding: const EdgeInsets.symmetric(vertical: 8), itemCount: data.keys.length, separatorBuilder: (context, index) => const SizedBox(height: 8), itemBuilder: (context, index) { final category = data.keys.elementAt(index); final items = data[category]!; return Container( margin: const EdgeInsets.symmetric(horizontal: 16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.04), blurRadius: 8, offset: const Offset(0, 2), ), ], ), child: Material( color: Colors.transparent, borderRadius: BorderRadius.circular(12), child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: Text( category, style: const TextStyle( fontSize: 18, fontWeight: FontWeight.w600, color: Colors.black, ), ), ), Container( padding: const EdgeInsets.symmetric( horizontal: 10, vertical: 4, ), decoration: BoxDecoration( color: AppConstants.primaryColor.withValues( alpha: 0.1, ), borderRadius: BorderRadius.circular(12), ), child: Text( '${items.length}', style: TextStyle( fontSize: 13, color: AppConstants.primaryColor, fontWeight: FontWeight.w600, ), ), ), ], ), const SizedBox(height: 12), Wrap( spacing: 10, runSpacing: 10, children: items.map((item) { return _buildCategoryChip(item, categoryType); }).toList(), ), ], ), ), ), ); }, ); } Widget _buildCategoryChip(String label, String categoryType) { return GestureDetector( onTap: () { final searchType = categoryType == '朝代分类' ? 'alias' : 'keywords'; Navigator.push( context, MaterialPageRoute( builder: (_) => CorrPage(label: label, searchType: searchType), ), ); }, child: Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10), decoration: BoxDecoration( color: AppConstants.primaryColor.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(20), border: Border.all( color: AppConstants.primaryColor.withValues(alpha: 0.3), width: 1, ), ), child: Text( label, style: TextStyle( color: AppConstants.primaryColor, fontSize: 14, fontWeight: FontWeight.w500, ), ), ), ); } }