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:go_router/go_router.dart'; import 'package:news_app/constant/api_const.dart'; import 'package:news_app/constant/color_res.dart'; import 'package:news_app/constant/size_res.dart'; import 'package:news_app/model/special_model.dart'; import 'package:news_app/provider/special_list_provider.dart'; import 'package:news_app/util/theme_util.dart'; import 'package:news_app/widget/empty_1_widget.dart'; import 'package:news_app/widget/load_image.dart'; import '../../model/special_detail.dart'; import '../../provider/special_detail_provider.dart'; import '../../widget/my_txt.dart'; /// @author: bo.zeng /// @email: cnhbwds@gmail.com /// @date: 2025 2025/4/29 22:16 /// @description: class SpecialListPage extends ConsumerStatefulWidget { static final String routeName = '/special/List'; final String cid; const SpecialListPage({super.key, required this.cid}); @override ConsumerState createState() => _SpecialListPageState(); } final specialListProvider = NotifierProvider( () { return SpecialListProvider(); }, ); final specialDetailProvider = NotifierProvider(() { return SpecialDetailProvider(); }); class _SpecialListPageState extends ConsumerState { int pageNum = 0; int currentTotal = 0; @override void initState() { super.initState(); setImmersiveStatusBar(); Future.wait([ ref .read(specialDetailProvider.notifier) .fetchSpecialDetail(cid: widget.cid), ref .read(specialListProvider.notifier) .fetchSpecialList(cid: widget.cid, pageNum: pageNum), ]); } void refresh() async {} Widget _buildHeader(BuildContext context, SpecialDetail data) { return SizedBox( width: double.infinity, height: 190.h, // 你自己项目里的适配高度 child: Stack( fit: StackFit.expand, // 横向完全撑满 children: [ LoadImage(data.logo ?? testImageUrlGirl, fit: BoxFit.cover), Padding( padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 40.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(height: 14.h), Row( children: [ GestureDetector( onTap: () => context.pop(), child: Icon(Icons.arrow_back_ios, color: Colors.white), ), ], ), ], ), ), ], ), ); } @override Widget build(BuildContext context) { final specialDetailData = ref.watch(specialDetailProvider); final specialListData = ref.watch(specialListProvider); ref.listen(specialListProvider, (pre, next) { currentTotal = next.total ?? 0; }); return Material( color: colorF5F7FD, child: EasyRefresh.builder( onRefresh: () async { pageNum = 0; await Future.wait([ ref .read(specialDetailProvider.notifier) .fetchSpecialDetail(cid: widget.cid), ref .read(specialListProvider.notifier) .fetchSpecialList(cid: widget.cid, pageNum: pageNum), ]); return IndicatorResult.success; }, onLoad: () async { if (currentTotal == specialListData.total) { return IndicatorResult.noMore; } else { pageNum++; await ref .read(specialListProvider.notifier) .fetchSpecialList(cid: widget.cid, pageNum: pageNum); return IndicatorResult.success; } }, childBuilder: (ctx, py) { return CustomScrollView( physics: py, slivers: [ SliverToBoxAdapter( child: _buildHeader(context, specialDetailData), ), SliverToBoxAdapter( child: Container( color: Colors.white, padding: EdgeInsets.all(horizontalPadding), child: myTxt( text: specialDetailData.name ?? "", fontSize: 15.sp, color: color333333, maxLines: 1, ), ), ), SliverPadding( padding: EdgeInsets.all(horizontalPadding), sliver: specialListData.records?.isEmpty == true ? SliverToBoxAdapter(child: Empty1widget()) : SliverList.separated( itemCount: specialListData.records?.length ?? 0, itemBuilder: (context, index) { final item = specialListData.records?[index]; return GestureDetector( onTap: () { context.push( "/news/detail", extra: item?.contentId, ); }, child: Container( padding: EdgeInsets.all(10.w), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(4.r), ), child: Row( children: [ Expanded( flex: 3, child: LoadImage( width: 93.w, height: 70.h, item?.imagesSrc?[0] ?? "", fit: BoxFit.cover, ), ), SizedBox(width: 8.w), Expanded( flex: 7, child: SizedBox( height: 72.h, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ myTxt( text: item?.title ?? "", fontSize: 15.sp, color: color333333, maxLines: 2, ), Row( spacing: 12.w, children: [ myTxt( text: item?.author ?? "", fontSize: 12.sp, color: colorA7A6A6, ), myTxt( text: item?.publishDate ?? "", fontSize: 12.sp, color: colorA7A6A6, ), ], ), ], ), ), ), ], ), ), ); }, separatorBuilder: (context, index) { return SizedBox(height: 10.h); }, ), ), ], ); }, ), ); } }