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:flutter_swiper_view/flutter_swiper_view.dart'; import 'package:go_router/go_router.dart'; import 'package:news_app/constant/color_res.dart'; import 'package:news_app/provider/activity_provider.dart'; import 'package:news_app/widget/load_image.dart'; import 'package:news_app/widget/my_txt.dart'; import 'package:shimmer/shimmer.dart'; import '../../constant/size_res.dart'; import '../../gen/assets.gen.dart'; import '../../model/activity_banner_model.dart'; import '../../model/activity_model.dart'; import '../../widget/list_animation_layout.dart'; import '../search/search_bar_widget.dart'; import '../video/video_detail_page.dart'; import 'activity_card_widget.dart'; /// @author: bo.zeng /// @email: cnhbwds@gmail.com /// @date: 2025 2025/4/9 16:00 /// @description: class MainActivityPage extends ConsumerStatefulWidget { const MainActivityPage({super.key}); @override ConsumerState createState() => _MainActivityPageState(); } final activityProvider = NotifierProvider( () => ActivityProvider(), ); class _MainActivityPageState extends ConsumerState with AutomaticKeepAliveClientMixin { int _page = 1; int _currentTotal = 0; @override void initState() { super.initState(); ref.read(activityProvider.notifier).fetchActivityBanner(); ref.read(activityProvider.notifier).fetchActivityList(page: _page); } void bannerTap(ActivityBannerModel model){ if (model.type == "activity") { if (model.contentType == "article") { context.push( "/activity/detail", extra: model.sourceId, ); } else if (model.contentType == "video") { context.push( '/video/detail', extra: VideoParam(id: model.sourceId ?? ""), ); } } } @override Widget build(BuildContext context) { super.build(context); final activityBanner = ref.watch( activityProvider.select((p) => p.activityBannerList), ); final activityList = ref.watch( activityProvider.select((p) => p.activityList), ); ref.listen(activityProvider.select((p) => p.activityList), ( pre, next, ) { _currentTotal = next?.total ?? 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: 1,), ), ], ), systemOverlayStyle: SystemUiOverlayStyle( statusBarColor: color5F59F7, statusBarIconBrightness: Brightness.light, // 状态栏图标颜色 ), ), body: EasyRefresh.builder( onRefresh: () async { _page = 1; await Future.wait([ ref.read(activityProvider.notifier).fetchActivityBanner(), // ref.read(activityProvider.notifier).fetchActivityVideo(), ref.read(activityProvider.notifier).fetchActivityList(page: _page), ]); return IndicatorResult.success; }, onLoad: () async { // 重新读取最新的 itemData final newItemData = ref.read(activityProvider).activityList; int total = newItemData?.total ?? 0; if (_currentTotal >= total) { return IndicatorResult.noMore; } else { _page += 1; await ref .read(activityProvider.notifier) .fetchActivityList(page: _page); 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( physics: physics, slivers: [ if (activityBanner.isNotEmpty) SliverToBoxAdapter( child: Container( padding: EdgeInsets.symmetric( horizontal: horizontalPadding, vertical: 10.h, ), height: 190.h, child: ClipRRect( //切圆角加在这里防止滑动的时候圆角消失 borderRadius: BorderRadius.circular(8), child: Swiper( autoplay: true, // 关键配置:关闭viewportFraction和pageSnapping viewportFraction: 1.0, onTap: (index){ bannerTap(activityBanner[index]); }, itemBuilder: (context, index) { return Stack( children: [ LoadImage( activityBanner[index].image ?? '', width: screenWidth, height: 190.h, fit: BoxFit.cover, holderImg: 'bignone', ), Positioned( bottom: 20.h, left: 20.h, right: 20.h, child: Padding( padding: EdgeInsets.only(bottom: 5.h), child: myTxt( text: activityBanner[index].title ?? '', color: Colors.white, fontSize: 15.sp, ), ), ), ], ); }, itemCount: activityBanner.length, pagination: const SwiperPagination(), ), ), ), ), (activityList?.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, ) : SliverPadding( padding: EdgeInsets.all(horizontalPadding), sliver: SliverList.separated( separatorBuilder: (context, index) { return SizedBox(height: 10.h); }, itemCount: (activityList?.records ?? []).length, itemBuilder: (context, index) { ActivityModelRecord item = activityList!.records![index]!; return GestureDetector( onTap: () { context.push( "/activity/detail", extra: item.contentId, ); }, child: ActivityCardWidget(cellData: item), ); }, ), ), ], ), ], ); }, ), ); } @override bool get wantKeepAlive => true; }