import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../constants/app_constants.dart'; import '../config/app_config.dart'; import '../utils/responsive_layout.dart'; import '../widgets/tabbed_nav_app_bar.dart'; import 'active/active_search_page.dart'; import 'active/category_page.dart'; import 'active/popular_page.dart'; import 'active/rate.dart'; import '../services/get/discover_controller.dart'; import '../services/get/theme_controller.dart'; import 'home/set/home-load.dart'; /// 时间: 2025-03-21 /// 功能: 发现页面 /// 介绍: 展示发现内容,包括热门话题、推荐内容等 /// 最新变化: 2026-04-02 支持深色模式 class DiscoverPage extends StatefulWidget { const DiscoverPage({super.key}); @override State createState() => _DiscoverPageState(); } class _DiscoverPageState extends State with SingleTickerProviderStateMixin { late TabController _tabController; final controller = Get.put(DiscoverController()); late ThemeController _themeController; @override void initState() { super.initState(); _themeController = Get.find(); GlobalTipsManager().init(); _tabController = TabController( length: controller.categories.length, vsync: this, ); _tabController.addListener(() { setState(() {}); }); } @override void dispose() { _tabController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Obx(() { final isDark = _themeController.isDarkModeRx.value; return GetBuilder( builder: (controller) { if (!controller.isInitialized.value) { return Scaffold( backgroundColor: isDark ? const Color(0xFF121212) : Colors.white, body: const Center(child: CircularProgressIndicator()), ); } return Scaffold( backgroundColor: isDark ? const Color(0xFF121212) : Colors.white, appBar: TabbedNavAppBar.build( title: '发现', tabLabels: controller.categories, tabController: _tabController, backgroundColor: isDark ? Colors.grey[900] : Colors.white, foregroundColor: isDark ? Colors.white : AppConstants.primaryColor, leading: controller.categories[_tabController.index] == '热门' ? _buildInfoButton(context, isDark) : null, actions: [ IconButton( icon: Icon( Icons.search, color: isDark ? Colors.white : AppConstants.primaryColor, ), onPressed: _showSearch, ), ], ), body: Column( children: [ ValueListenableBuilder( valueListenable: GlobalTipsManager().enabledNotifier, builder: (context, isGlobalTipsEnabled, child) { if (controller.categories[_tabController.index] != '搜索' && isGlobalTipsEnabled && controller.showTips.value) { return _buildTopicChips(controller, isDark); } return const SizedBox.shrink(); }, ), Expanded( child: TabBarView( controller: _tabController, children: controller.categories.map((category) { if (category == '分类') { return const CategoryPage(); } if (category == '热门') { return const PopularPage(); } if (category == '搜索') { return const ActiveSearchPage(); } if (category == '活跃') { return const RatePage(); } return _buildContentList(category, controller, isDark); }).toList(), ), ), ], ), ); }, ); }); } Widget _buildTopicChips(DiscoverController controller, bool isDark) { return Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), color: isDark ? const Color(0xFF1E1E1E) : Colors.grey[50], child: Row( children: [ Expanded( child: Text( '💡 探索更多精彩内容,发现你感兴趣的诗词世界', style: TextStyle( color: AppConstants.primaryColor, fontSize: 14, fontWeight: FontWeight.w400, ), ), ), GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { controller.toggleTips(); }, child: Container( width: 30, height: 30, decoration: BoxDecoration( color: isDark ? Colors.grey[800] : Colors.grey.withValues(alpha: 0.1), shape: BoxShape.circle, ), child: Icon( Icons.close, size: 16, color: isDark ? Colors.grey[400] : Colors.grey[600], ), ), ), ], ), ); } Widget _buildContentList( String category, DiscoverController controller, bool isDark, ) { final items = List.generate(20, (index) => index); return RefreshIndicator( onRefresh: controller.refreshContent, child: ListView.separated( // 添加底部内边距,让内容延伸到导航栏下方,实现玻璃效果 padding: EdgeInsets.only( left: 16, right: 16, top: 16, bottom: AppConfig.liquidGlassTotalHeight + 16, ), itemCount: items.length, separatorBuilder: (context, index) => const SizedBox(height: 12), itemBuilder: (context, index) => _buildContentCard(context, index, category, controller, isDark), ), ); } Widget _buildContentCard( BuildContext context, int index, String category, DiscoverController controller, bool isDark, ) { return ResponsiveCard( onTap: () => controller.showContentDetails(context, index, category), backgroundColor: isDark ? const Color(0xFF1E1E1E) : Colors.white, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ CircleAvatar( radius: 20, backgroundColor: AppConstants.primaryColor.withValues( alpha: 0.1, ), child: Icon( Icons.person, color: AppConstants.primaryColor, size: 20, ), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '用户${index + 1}', style: TextStyle( fontWeight: FontWeight.bold, color: isDark ? Colors.white : Colors.black87, ), ), Text( '${index + 1}小时前', style: TextStyle( color: isDark ? Colors.grey[400] : Colors.grey[600], ), ), ], ), ), IconButton( icon: Icon( Icons.more_horiz, color: isDark ? Colors.grey[400] : Colors.grey[600], ), onPressed: () => controller.showMoreOptions(context, index), ), ], ), const SizedBox(height: 12), Text( '这是$category分类下的精彩内容${index + 1}', style: TextStyle( fontWeight: FontWeight.w600, fontSize: 16, color: isDark ? Colors.white : Colors.black87, ), ), const SizedBox(height: 8), Text( '这里是内容的详细描述,包含了丰富的信息和有趣的内容。这个内容来自于$category分类,展示了最新的趋势和热门话题。', style: TextStyle( color: isDark ? Colors.grey[400] : Colors.grey[700], ), maxLines: 3, overflow: TextOverflow.ellipsis, ), const SizedBox(height: 12), if (index % 3 == 0) Container( width: double.infinity, height: 200, decoration: BoxDecoration( color: isDark ? AppConstants.secondaryColor.withValues(alpha: 0.2) : AppConstants.secondaryColor.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(12), ), child: Icon( Icons.image, size: 50, color: isDark ? AppConstants.secondaryColor.withValues(alpha: 0.6) : AppConstants.secondaryColor, ), ), const SizedBox(height: 12), Row( children: [ _buildActionButton( Icons.favorite_border, '${(index + 1) * 23}', () => controller.likeContent(index), isDark, ), const SizedBox(width: 16), _buildActionButton( Icons.chat_bubble_outline, '${(index + 1) * 8}', () => controller.commentContent(index), isDark, ), const SizedBox(width: 16), _buildActionButton( Icons.share, '分享', () => controller.shareContent(index), isDark, ), const Spacer(), _buildActionButton( Icons.bookmark_border, '收藏', () => controller.bookmarkContent(index), isDark, ), ], ), ], ), ); } Widget _buildActionButton( IconData icon, String label, VoidCallback onPressed, bool isDark, ) { return GestureDetector( onTap: onPressed, child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( icon, size: 18, color: isDark ? Colors.grey[400] : Colors.grey[600], ), const SizedBox(width: 4), Text( label, style: TextStyle( fontSize: 12, color: isDark ? Colors.grey[400] : Colors.grey[600], ), ), ], ), ); } void _showSearch() { Get.to(const ActiveSearchPage()); } Widget _buildInfoButton(BuildContext context, bool isDark) { return Builder( builder: (buttonContext) { return IconButton( icon: Icon( Icons.info_outline, color: isDark ? Colors.white : AppConstants.primaryColor, ), onPressed: () => _showHotInfoPopup(buttonContext, isDark), ); }, ); } void _showHotInfoPopup(BuildContext context, bool isDark) { final RenderBox button = context.findRenderObject() as RenderBox; final RenderBox overlay = Navigator.of(context).overlay!.context.findRenderObject() as RenderBox; final Offset buttonPosition = button.localToGlobal( Offset.zero, ancestor: overlay, ); late OverlayEntry infoOverlayEntry; infoOverlayEntry = OverlayEntry( builder: (context) => Positioned( left: buttonPosition.dx, top: buttonPosition.dy + button.size.height + 8, child: Material( color: Colors.transparent, child: GestureDetector( onTap: () { infoOverlayEntry.remove(); }, child: Container( width: 220, padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: isDark ? const Color(0xFF2A2A2A) : Colors.white, borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: isDark ? 0.4 : 0.15), blurRadius: 12, offset: const Offset(0, 4), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( Icons.local_fire_department, color: AppConstants.primaryColor, size: 20, ), const SizedBox(width: 8), Text( '热门排行榜', style: TextStyle( fontWeight: FontWeight.bold, fontSize: 14, color: isDark ? Colors.white : Colors.black87, ), ), ], ), const SizedBox(height: 8), Text( '展示诗词的浏览量和点赞数排行,包括总榜、日榜、月榜三种类型。帮助您发现最受欢迎的诗词作品。', style: TextStyle( fontSize: 12, color: isDark ? Colors.grey[400] : Colors.grey[600], height: 1.5, ), ), ], ), ), ), ), ), ); Overlay.of(context).insert(infoOverlayEntry); Future.delayed(const Duration(seconds: 3), () { infoOverlayEntry.remove(); }); } }