import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:wow_english/common/widgets/we_app_bar.dart'; import 'package:wow_english/models/course_module_entity.dart'; import 'package:wow_english/route/route.dart'; import '../../common/utils/click_with_music_controller.dart'; import '../../utils/audio_player_util.dart'; import '../section/courese_module_model.dart'; import 'bloc/module_bloc.dart'; import 'widgets/module_item_widget.dart'; // 课程阶段(模块)列表页 class CourseModulePage extends StatelessWidget { const CourseModulePage({super.key, this.starPageIndex}); final int? starPageIndex; @override Widget build(BuildContext context) { return BlocProvider( create: (context) => ModuleBloc( starPageIndex ?? 0, PageController(initialPage: starPageIndex ?? 0, viewportFraction: 0.3), )..add(RequestDataEvent()), child: _LessonPageView(), ); } } class _LessonPageView extends StatelessWidget { final double _cardHeight = 240.h; final double _scale = 0.8; @override Widget build(BuildContext context) { return BlocListener( listener: (context, state) {}, child: Scaffold( appBar: const WEAppBar(), body: _lessViewWidget(), ), ); } Widget _lessViewWidget() => BlocBuilder(builder: (context, state) { final bloc = BlocProvider.of(context); return Center( child: SafeArea( child: Column( children: [ SizedBox( height: _cardHeight, child: PageView.builder( itemCount: bloc.listData.length, controller: bloc.pageController, onPageChanged: (int index) { bloc.add(PageViewChangeIndexEvent(index)); }, itemBuilder: (context, index) => _itemTransCard(index)), ), 32.verticalSpace, SizedBox( height: 32.h, width: 66.w * bloc.listData.length, child: ListView.builder( itemCount: bloc.listData.length, scrollDirection: Axis.horizontal, itemBuilder: (BuildContext context, int index) { CourseModuleEntity? model = bloc.listData[index]; return Container( height: 32.h, width: 66.w, padding: const EdgeInsets.symmetric(horizontal: 5), child: GestureDetector( onTap: () { if (index == bloc.currentPageIndex) { return; } int mill = (index - bloc.currentPageIndex) > 0 ? 100 * (index - bloc.currentPageIndex) : 100 * (bloc.currentPageIndex - index); bloc.pageController.animateToPage(index, duration: Duration(milliseconds: mill), curve: Curves.ease); }, child: Container( height: bloc.currentPageIndex == index ? 32 : 20, decoration: BoxDecoration( // color: bloc.currentPageIndex == index // ? Colors.red // : Colors.white, color: CourseModuleModel(model?.code ?? 'Phase-1') .color .withOpacity( bloc.currentPageIndex == index ? 1 : 0.35), borderRadius: BorderRadius.circular(5.r), border: Border.all( width: 0.5, color: Colors.black, ), ), alignment: Alignment.center, child: Text( (index + 1).toString(), style: TextStyle( color: bloc.currentPageIndex == index ? Colors.white : Colors.black), ), ), ), ); }), ) ], ), ), ); }); Widget _itemTransCard(int index) => BlocBuilder(builder: (context, state) { final bloc = BlocProvider.of(context); Matrix4 matrix4 = Matrix4.identity(); if (index == bloc.currentPageIndex.floor()) { //当前的item double currScale = (1 - (bloc.currentPageIndex - index) * (1 - _scale)).toDouble(); var currTrans = _cardHeight * (1 - currScale) / 2; matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0) ..setTranslationRaw(0.0, currTrans, 0.0); } else if (index == bloc.currentPageIndex.floor() + 1) { //右边的item var currScale = _scale + (bloc.currentPageIndex - index + 1) * (1 - _scale); var currTrans = _cardHeight * (1 - currScale) / 2; matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0) ..setTranslationRaw(0.0, currTrans, 0.0); } else if (index == bloc.currentPageIndex - 1) { //左边 var currScale = (1 - (bloc.currentPageIndex - index) * (1 - _scale)).toDouble(); var currTrans = _cardHeight * (1 - currScale) / 2; matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0) ..setTranslationRaw(0.0, currTrans, 0.0); } else { //其他,不在屏幕显示的item matrix4 = Matrix4.diagonal3Values(1.0, _scale, 1.0) ..setTranslationRaw(0.0, _cardHeight * (1 - _scale) / 2, 0.0); } CourseModuleEntity? model = bloc.listData[index]; return Transform( transform: matrix4, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 10), child: ModuleItemWidget( model: model, isSelected: bloc.currentPageIndex == index, onClickEvent: () { ///todo 不同阶段音乐文件待提供 ClickWithMusicController.instance.playMusicAndPerformAction( context, AudioPlayerUtilType.welcomeToWow, () => pushNamedAndRemoveUntil( AppRouteName.courseUnit, (route) => route.isFirst, arguments: {'courseModuleEntity': model})); }, ), ), ); }); }