import 'package:cached_network_image/cached_network_image.dart'; import 'package:easy_refresh/easy_refresh.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:go_router/go_router.dart'; import 'package:news_app/constant/size_res.dart'; import 'package:news_app/ui/topic/topic_item_widget.dart'; import 'package:news_app/widget/load_image.dart'; import 'package:shimmer/shimmer.dart'; import '../../constant/color_res.dart'; import '../../constant/config.dart'; import '../../gen/assets.gen.dart'; import '../../model/topic_item_model.dart'; import '../../provider/topic_list_provider.dart'; import '../../provider/topic_provider.dart'; import '../../widget/list_animation_layout.dart'; import '../../widget/my_txt.dart'; import '../search/search_bar_widget.dart'; /// @author: bo.zeng /// @email: cnhbwds@gmail.com /// @date: 2025 2025/4/9 16:00 /// @description: class MainTopicPage extends ConsumerStatefulWidget { const MainTopicPage({super.key}); @override ConsumerState createState() => _MainTopicPageState(); } final topicProvider = NotifierProvider( () => TopicProvider(), ); final topicListProvider = NotifierProvider( () => TopicListProvider(), ); class _MainTopicPageState extends ConsumerState with AutomaticKeepAliveClientMixin { int _page = 1; int _currentTotal = 0; @override void initState() { super.initState(); ref.read(topicProvider.notifier).fetchTopicHot(); ref.read(topicProvider.notifier).fetchRankHot(); ref.read(topicListProvider.notifier).fetchList(page: _page, tid: ""); eventBus.on().listen((event) { if (event == "topicCall") { _page = 1; ref.read(topicListProvider.notifier).fetchList(page: _page, tid: ""); } }); } void longTapAction(String contentId) {} @override Widget build(BuildContext context) { super.build(context); final hotData = ref.watch(topicProvider.select((p) => p.topicHotList)); final rankData = ref.watch(topicProvider.select((p) => p.topicRankList)); final itemData = ref.watch(topicListProvider); ref.listen(topicListProvider.select((p) => p.records), (previous, next) { _currentTotal = next?.length ?? 0; }); return Scaffold( appBar: AppBar( elevation: 0, // 移除阴影 scrolledUnderElevation: 0, // 禁用滚动时的阴影变化 backgroundColor: color5F59F7, centerTitle: true, title: Row( spacing: 10.w, children: [ Image.asset(Assets.images.logo.path, width: 70.w), Expanded(child: SearchBarWidget(tabIndex: 3)), ], ), systemOverlayStyle: SystemUiOverlayStyle( statusBarColor: color5F59F7, statusBarIconBrightness: Brightness.light, // 状态栏图标颜色 ), ), body: EasyRefresh.builder( onRefresh: () async { _page = 1; await Future.wait([ ref.read(topicProvider.notifier).fetchTopicHot(), ref.read(topicProvider.notifier).fetchRankHot(), ref .read(topicListProvider.notifier) .fetchList(page: _page, tid: ""), ]); return IndicatorResult.success; }, onLoad: () async { // 重新读取最新的 itemData final newItemData = ref.read(topicListProvider); int total = newItemData.total ?? 0; if (_currentTotal >= total) { return IndicatorResult.noMore; } else { _page += 1; await ref .read(topicListProvider.notifier) .fetchList(page: _page, tid: ""); return IndicatorResult.success; } }, childBuilder: (context, physics) { return Stack( children: [ Positioned( child: Container( height: 100.h, decoration: BoxDecoration( gradient: LinearGradient( colors: [color5F59F7, color6592FD, Colors.white], begin: Alignment.topCenter, end: Alignment.bottomCenter, ), ), ), ), CustomScrollView( slivers: [ if (hotData.isNotEmpty) SliverPadding( padding: EdgeInsets.symmetric( vertical: horizontalPadding, horizontal: horizontalPadding, ), sliver: SliverToBoxAdapter( child: Row( spacing: 5.w, children: [ Icon( Icons.fire_hydrant_alt_rounded, size: 20, color: Colors.white, ), myTxt( text: "热门话题", color: Colors.white, fontWeight: FontWeight.bold, fontSize: 18.sp, ), ], ), ), ), SliverPadding( padding: EdgeInsets.symmetric( horizontal: horizontalPadding, ), sliver: SliverToBoxAdapter( child: Builder( builder: (context) { if (hotData.isNotEmpty) { return Row( spacing: horizontalPadding, children: List.generate(hotData.length, ( index, ) { return Expanded( child: Stack( alignment: Alignment.bottomLeft, children: [ AspectRatio( aspectRatio: 16 / 9, child: ClipRRect( borderRadius: BorderRadius.circular( 8.r, ), child: CachedNetworkImage( fit: BoxFit.cover, imageUrl: hotData[index].image ?? "", ), ), ), Positioned( bottom: 5.h, left: 5.h, right: 5.h, child: myTxt( text: hotData[index].title ?? "", fontSize: 14.sp, color: Colors.white, maxLines: 2, // 限制文本的最大行数 ), ), ], ), ); }), ); } else { return const SizedBox.shrink(); } }, ), ), ), SliverPadding( padding: EdgeInsets.symmetric( vertical: horizontalPadding, horizontal: horizontalPadding, ), sliver: SliverToBoxAdapter( child: Row( spacing: 5.w, children: [ // Image.asset(Assets.images.fire.path, width: 13.w), LoadAssetImage('topic_fire', width: 13.w), myTxt( text: "精选话题", color: Colors.black, fontWeight: FontWeight.bold, fontSize: 18.sp, ), ], ), ), ), SliverToBoxAdapter( child: Container( margin: EdgeInsets.symmetric( horizontal: horizontalPadding, ), padding: EdgeInsets.all(8.w), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8.r), color: Colors.white, ), child: Builder( builder: (context) { return Column( spacing: 8.h, children: List.generate(rankData.length, ( index, ) { return GestureDetector( onTap: () { context.push( "/topic/list", extra: rankData[index].contentId, ); }, child: Row( spacing: 5.w, children: [ SizedBox(width: 1.w), myTxt( text: "${index + 1}", fontWeight: FontWeight.w900, color: index <= 3 ? Colors.red : Colors.black, fontSize: 15.sp, ), Flexible( child: myTxt( text: rankData[index].content ?? "", color: Colors.black, fontSize: 15.sp, maxLines: 1, ), ), ], ), ); }), ); }, ), ), ), (itemData.records ?? []).isEmpty ? SliverList.separated( separatorBuilder: (context, index) { return Container(height: 10.h); }, itemBuilder: (context, index) { return Shimmer.fromColors( baseColor: Color(0xffe5e5e5), highlightColor: Color(0xfff5f5f5), child: AnimationItem(), ); }, itemCount: 20, ) : SliverList( delegate: SliverChildBuilderDelegate((context, index) { return GestureDetector( onTap: () { context.push( "/topic/detail", extra: itemData.records?[index].contentId, ); }, child: Padding( padding: EdgeInsets.only( left: horizontalPadding, right: horizontalPadding, top: horizontalPadding, ), child: TopicItemWidget( longTapAction, item: itemData.records?[index], ), ), ); }, childCount: itemData.records?.length ?? 0), ), ], physics: physics, ), ], ); }, ), ); } @override bool get wantKeepAlive => true; }