import 'package:easy_refresh/easy_refresh.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_swiper_view/flutter_swiper_view.dart'; import 'package:go_router/go_router.dart'; import 'package:news_app/constant/size_res.dart'; import 'package:news_app/extension/base.dart'; import 'package:news_app/ui/news/special_list_page.dart'; import 'package:news_app/widget/my_txt.dart'; import 'package:shimmer/shimmer.dart'; import '../../constant/color_res.dart'; import '../../gen/assets.gen.dart'; import '../../model/activity_banner_model.dart'; import '../../model/news_data_model.dart'; import '../../provider/news_provider.dart'; import '../../util/time_util.dart'; import '../../widget/list_animation_layout.dart'; import '../../widget/load_image.dart'; /// @author: bo.zeng /// @email: cnhbwds@gmail.com /// @date: 2025 2025/4/9 16:00 /// @description: class NewsChildMainPage extends ConsumerStatefulWidget { final int tabIndex; const NewsChildMainPage({super.key, required this.tabIndex}); @override ConsumerState createState() => _NewsChildMainPageState(); } final newsProvider = NotifierProvider.family(() { return NewsNotifier(); }); class _NewsChildMainPageState extends ConsumerState { final Map _iconMap = { 0: Assets.images.zxzxIcon.path, 1: Assets.images.zxzxIcon1.path, 2: Assets.images.zxzxIcon2.path, 3: Assets.images.zxzxIcon2.path, }; int pageNum = 1; int total = 0; @override void initState() { super.initState(); ref.read(newsProvider(widget.tabIndex).notifier).fetchNewsItemList(pageNum); ref.read(newsProvider(widget.tabIndex).notifier).fetchBannerList(); } @override Widget build(BuildContext context) { // super.build(context); // consoleLog(widget.tabIndex); final data = ref.watch( newsProvider(widget.tabIndex).select((p) => p.newsDataModel), ); final bannerList = ref.watch( newsProvider(widget.tabIndex).select((p) => p.bannerList), ); ref.listen(newsProvider(widget.tabIndex).select((p) => p.newsDataModel), ( p, next, ) { total = next.records?.length ?? 0; }); return EasyRefresh.builder( onRefresh: () async { // if (bannerList.isEmpty) { await ref .read(newsProvider(widget.tabIndex).notifier) .fetchBannerList(); // } pageNum = 1; await ref .read(newsProvider(widget.tabIndex).notifier) .fetchNewsItemList(pageNum); return IndicatorResult.success; }, onLoad: () async { if (total >= data.total.safeValue) { return IndicatorResult.noMore; } else { pageNum += 1; await ref .read(newsProvider(widget.tabIndex).notifier) .fetchNewsItemList(pageNum); } }, childBuilder: (context, physics) { return Padding( padding: EdgeInsets.symmetric( horizontal: horizontalPadding, ), child: CustomScrollView( physics: physics, slivers: [ //注意独家的部顶没有Banner if (widget.tabIndex != 5) SliverToBoxAdapter( child: Container( margin: EdgeInsets.only(top: 10.h), height: 300.h, child: Builder( builder: (context) { //其他都是banner return buildBanner( widget.tabIndex, bannerList, context, ); }, ), ), ), SliverToBoxAdapter(child: _buildTitle(widget.tabIndex)), if (widget.tabIndex <= 3) SliverToBoxAdapter( child: Container( margin: EdgeInsets.only( left: 10.w, top: 16.h, bottom: 10.h, ), alignment: Alignment.centerLeft, child: Image.asset(_iconMap[widget.tabIndex]!, scale: 2.5), ), ), // if (widget.tabIndex == 3) // SliverToBoxAdapter(child: _buildRowItem()), //新闻列表 (data.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.separated( separatorBuilder: (context, index) { return Container(height: 10.h); }, itemBuilder: (context, index) { // if (widget.tabIndex == 4) { // return _buildLiquorItem(data.records?[index], context); // } else if (widget.tabIndex == 5) { return Container( child: _buildExclusiveWidget( data.records?[index], index, context, ), ); } else { return Container( child: buildNewsNewItem(data.records?[index], context), ); //buildNewsNewItem(data.records?[index], context); } }, itemCount: data.records?.length, ) ], ), ); }, ); } // @override // bool get wantKeepAlive => true; } Widget buildBanner( int tabIndex, List bannerList, BuildContext context, ) { return Swiper( autoplay: true, // 关键配置:关闭viewportFraction和pageSnapping viewportFraction: 1.0, onTap: (index) { final item = bannerList[index]; if ((item.sourceId ?? '').isNotEmpty) { if (item.type == 'column') { context.push(SpecialListPage.routeName, extra: item.sourceId); } else { context.push("/news/detail", extra: item.sourceId); } } }, itemBuilder: (context, index) { if (bannerList.isEmpty) { return Container(); } // int start = tabIndex * banners.length; // int end = start + banners.length; return ClipRRect( borderRadius: BorderRadius.circular(8), child: Stack( children: [ LoadImage( bannerList[index].image ?? '', width: screenWidth, height:300.h, fit: BoxFit.cover, holderImg: 'bignone', ), if (tabIndex <= 3 || tabIndex == 5) Positioned( bottom: 20.h, left: 15.h, right: 20.h, child: Builder( builder: (context) { if (tabIndex == 3) { return Padding( padding: EdgeInsets.only(bottom: 5.h), child: myTxt( text: bannerList[index].title ?? '', color: Colors.white, fontSize: 15.sp, ), ); } else { return Column( spacing: 1.h, crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(height: 3.h), myTxt( text: bannerList[index].title ?? '', color: Colors.white, fontSize: 15.sp, ), ], ); } }, ), ), ], ), ); }, itemCount: bannerList.length, pagination: const SwiperPagination(), ); } Widget buildNewsNewItem(NewsRecord? item, BuildContext context) { if (item == null) { return const SizedBox.shrink(); } int imageLength = item.imagesSrc?.length ?? 0; return GestureDetector( onTap: () => context.push("/news/detail", extra: item.contentId), child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(8.r), color: Colors.white, ), padding: EdgeInsets.all(10.w), child: Builder( builder: (context) { if (imageLength == 0 || imageLength == 3) { return _buildNewsVertical(item); } else { //别的一律当1张图处理 return Row( children: [ Expanded( child: SizedBox( height: 70.h, child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ myTxt( text: item.title ?? "", fontWeight: FontWeight.bold, color: color333333, fontSize: 15.sp, maxLines: 2, ), Row( spacing: 20.w, children: [ myTxt( text: item.author ?? "新华日报", fontSize: 12.sp, color: colorA7A6A6, ), myTxt( text: item.publishDateStr ?? "4天前", fontSize: 12.sp, color: colorA7A6A6, ), ], ), ], ), ), ), SizedBox(width: 5.w), LoadImage( width: 93.w, height: 70.h, item.imagesSrc?[0] ?? "", fit: BoxFit.cover, ), ], ); } }, ), ), ); } Widget _buildNewsVertical(NewsRecord item) { return Column( spacing: 5.h, crossAxisAlignment: CrossAxisAlignment.start, children: [ myTxt( text: item.title ?? "", fontWeight: FontWeight.bold, color: color333333, fontSize: 15.sp, maxLines: 1, ), myTxt( text: item.summary ?? "", color: color666666, fontSize: 12.sp, maxLines: 1, ), if (item.imagesSrc?.isNotEmpty == true) Row( children: item.imagesSrc ?.map((e) => Expanded(child: LoadImage(e, fit: BoxFit.cover))) .toList() ?? [], ), Row( spacing: 20.w, children: [ myTxt(text: item.author ?? "", fontSize: 12.sp, color: colorA7A6A6), myTxt( text: item.publishDateStr ?? "", fontSize: 12.sp, color: colorA7A6A6, ), ], ), ], ); } Widget _buildTitle(int index) { switch (index) { case 0: return Container(); case 1: return Container(); case 2: return Container(); case 3: return Container(); case 4: return Padding( padding: EdgeInsets.only( top: 10.h, bottom: 10.h, left: horizontalPadding, ), child: myTxt( text: "深一度(行业观察)", color: Colors.black, fontWeight: FontWeight.bold, fontSize: 15.sp, ), ); default: return SizedBox.shrink(); } } //独家widget Widget _buildExclusiveWidget( NewsRecord? item, int index, BuildContext context, ) { return GestureDetector( onTap: () { context.push("/news/detail", extra: item?.contentId ?? ''); }, child: Container( margin: EdgeInsets.only(bottom: 15.h), child: Column( spacing: 8.h, children: [ Row( spacing: 10.w, children: [ Image.asset(Assets.images.hotDicsussion.path, width: 50.w), Flexible( child: myTxt( text: item?.title ?? "百年后,小西湖终于又有了湖", color: index == 0 ? Colors.white : color333333, fontSize: 16.sp, fontWeight: FontWeight.bold, maxLines: 1, ), ), ], ), ClipRRect( borderRadius: BorderRadius.circular(8.r), child: LoadImage( item?.imagesSrc?.first ?? '', height: 300.h, width: screenWidth, fit: BoxFit.cover, holderImg: 'bignone', ), ), Row( spacing: 10.w, children: [ myTxt( text: item?.author ?? "新华日报", color: colorA7A6A6, fontSize: 12.sp, fontWeight: FontWeight.bold, ), SizedBox(width: 5.w), myTxt( text:item?.publishDateStr ?? '', color: colorA7A6A6, fontSize: 12.sp, fontWeight: FontWeight.bold, ), ], ), ], ), ), ); }