Commit 842b7132f392105f396d8d52fba4d9bb321abe8f

Authored by liangchengyou
1 parent c95453ce

feat:磨耳朵/练习页面调整

Showing 37 changed files with 526 additions and 1038 deletions
lib/pages/home/bloc/home_bloc.dart
@@ -21,23 +21,10 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> { @@ -21,23 +21,10 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
21 on<RequestDataEvent>(_requestData); 21 on<RequestDataEvent>(_requestData);
22 } 22 }
23 23
24 - Future<void> requestData() async {  
25 - try {  
26 - await loading(() async {  
27 - _modelData = await HomeDao.courseLesson(moduleId: moduleId??'');  
28 - emit(HomeDataLoadState());  
29 - });  
30 - } catch (e) {  
31 - if (e is ApiException) {  
32 - EasyLoading.showToast(e.message.toString());  
33 - }  
34 - }  
35 - }  
36 -  
37 void _requestData(RequestDataEvent event, Emitter<HomeState> emitter) async { 24 void _requestData(RequestDataEvent event, Emitter<HomeState> emitter) async {
38 try { 25 try {
39 await loading(() async { 26 await loading(() async {
40 - HomeDao.courseLesson(); 27 + _modelData = await HomeDao.courseLesson(moduleId: moduleId??'');
41 emitter(HomeDataLoadState()); 28 emitter(HomeDataLoadState());
42 }); 29 });
43 } catch (e) { 30 } catch (e) {
lib/pages/home/home_page.dart
@@ -20,7 +20,7 @@ class HomePage extends StatelessWidget { @@ -20,7 +20,7 @@ class HomePage extends StatelessWidget {
20 @override 20 @override
21 Widget build(BuildContext context) { 21 Widget build(BuildContext context) {
22 return BlocProvider( 22 return BlocProvider(
23 - create: (context) => HomeBloc(moduleId)..requestData(), 23 + create: (context) => HomeBloc(moduleId)..add(RequestDataEvent()),
24 child: _HomePageView(), 24 child: _HomePageView(),
25 ); 25 );
26 } 26 }
@@ -37,7 +37,8 @@ class _HomePageView extends StatelessWidget { @@ -37,7 +37,8 @@ class _HomePageView extends StatelessWidget {
37 } else if (type == HeaderActionType.shop) { 37 } else if (type == HeaderActionType.shop) {
38 Navigator.of(AppRouter.context).pushNamed(AppRouteName.shop); 38 Navigator.of(AppRouter.context).pushNamed(AppRouteName.shop);
39 } else if (type == HeaderActionType.user) { 39 } else if (type == HeaderActionType.user) {
40 - Navigator.of(AppRouter.context).pushNamed(AppRouteName.user); 40 + Navigator.of(AppRouter.context).pushNamed(AppRouteName.topicPic);
  41 + // Navigator.of(AppRouter.context).pushNamed(AppRouteName.user);
41 } else { 42 } else {
42 // Navigator.of(AppRouter.context).pushNamed(AppRouteName.topicPic); 43 // Navigator.of(AppRouter.context).pushNamed(AppRouteName.topicPic);
43 // Navigator.of(AppRouter.context).pushNamed(AppRouteName.topicWord); 44 // Navigator.of(AppRouter.context).pushNamed(AppRouteName.topicWord);
@@ -132,6 +133,7 @@ class _HomePageView extends StatelessWidget { @@ -132,6 +133,7 @@ class _HomePageView extends StatelessWidget {
132 'blue-positive'.assetPng, 133 'blue-positive'.assetPng,
133 height: 47.h, 134 height: 47.h,
134 width: 80.w, 135 width: 80.w,
  136 + // color: Colors.red,
135 ), 137 ),
136 ], 138 ],
137 ), 139 ),
lib/pages/lessons/bloc/lesson_bloc.dart
1 import 'package:flutter/cupertino.dart'; 1 import 'package:flutter/cupertino.dart';
2 import 'package:flutter_bloc/flutter_bloc.dart'; 2 import 'package:flutter_bloc/flutter_bloc.dart';
  3 +import 'package:flutter_easyloading/flutter_easyloading.dart';
3 import 'package:wow_english/common/request/dao/home_dao.dart'; 4 import 'package:wow_english/common/request/dao/home_dao.dart';
4 import 'package:wow_english/common/request/exception.dart'; 5 import 'package:wow_english/common/request/exception.dart';
5 import 'package:wow_english/models/course_module_entity.dart'; 6 import 'package:wow_english/models/course_module_entity.dart';
@@ -25,26 +26,28 @@ class LessonBloc extends Bloc&lt;LessonEvent, LessonState&gt; { @@ -25,26 +26,28 @@ class LessonBloc extends Bloc&lt;LessonEvent, LessonState&gt; {
25 LessonBloc(this.pageIndex,this.pageController) : super(LessonInitial()) { 26 LessonBloc(this.pageIndex,this.pageController) : super(LessonInitial()) {
26 _currentPageIndex = pageIndex; 27 _currentPageIndex = pageIndex;
27 on<PageViewChangeIndexEvent>(_pageIndexChange); 28 on<PageViewChangeIndexEvent>(_pageIndexChange);
  29 + on<RequestDataEvent>(_requestData);
28 } 30 }
29 31
30 - Future<void> requestData() async { 32 +
  33 + void _pageIndexChange(PageViewChangeIndexEvent event,Emitter<LessonState> emitter) async {
  34 + _currentPageIndex = event.index;
  35 + emitter(PageIndexChangeState());
  36 + }
  37 +
  38 + void _requestData(RequestDataEvent event, Emitter<LessonState> emitter) async {
31 try { 39 try {
32 await loading(() async { 40 await loading(() async {
33 _listData = await HomeDao.courseModule()??[]; 41 _listData = await HomeDao.courseModule()??[];
34 - emit(LessonDataLoadState()); 42 + emitter(LessonDataLoadState());
35 }); 43 });
36 } catch (e) { 44 } catch (e) {
37 if (e is ApiException) { 45 if (e is ApiException) {
38 - 46 + EasyLoading.showToast(e.message??'请求失败,请检查网络连接');
39 } 47 }
40 } 48 }
41 } 49 }
42 50
43 - void _pageIndexChange(PageViewChangeIndexEvent event,Emitter<LessonState> emitter) async {  
44 - _currentPageIndex = event.index;  
45 - emitter(PageIndexChangeState());  
46 - }  
47 -  
48 @override 51 @override
49 Future<void> close() { 52 Future<void> close() {
50 pageController.dispose(); 53 pageController.dispose();
lib/pages/lessons/bloc/lesson_event.dart
@@ -7,3 +7,5 @@ class PageViewChangeIndexEvent extends LessonEvent { @@ -7,3 +7,5 @@ class PageViewChangeIndexEvent extends LessonEvent {
7 final int index; 7 final int index;
8 PageViewChangeIndexEvent(this.index); 8 PageViewChangeIndexEvent(this.index);
9 } 9 }
  10 +
  11 +class RequestDataEvent extends LessonEvent {}
lib/pages/lessons/lesson_page.dart
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
2 import 'package:flutter_bloc/flutter_bloc.dart'; 2 import 'package:flutter_bloc/flutter_bloc.dart';
3 -import 'package:flutter_easyloading/flutter_easyloading.dart';  
4 import 'package:flutter_screenutil/flutter_screenutil.dart'; 3 import 'package:flutter_screenutil/flutter_screenutil.dart';
5 import 'package:wow_english/common/extension/string_extension.dart'; 4 import 'package:wow_english/common/extension/string_extension.dart';
6 import 'package:wow_english/common/widgets/we_app_bar.dart'; 5 import 'package:wow_english/common/widgets/we_app_bar.dart';
@@ -24,7 +23,7 @@ class LessonPage extends StatelessWidget { @@ -24,7 +23,7 @@ class LessonPage extends StatelessWidget {
24 initialPage: starPageIndex??0, 23 initialPage: starPageIndex??0,
25 viewportFraction: 0.3 24 viewportFraction: 0.3
26 ), 25 ),
27 - )..requestData(), 26 + )..add(RequestDataEvent()),
28 child: _LessonPageView(), 27 child: _LessonPageView(),
29 ); 28 );
30 } 29 }
lib/pages/listen/bloc/listen_bloc.dart
@@ -13,20 +13,19 @@ part &#39;listen_state.dart&#39;; @@ -13,20 +13,19 @@ part &#39;listen_state.dart&#39;;
13 13
14 class ListenBloc extends Bloc<ListenEvent, ListenState> { 14 class ListenBloc extends Bloc<ListenEvent, ListenState> {
15 15
16 - List<ListenEntity?>? _listData;  
17 - List<ListenEntity?>? get listData => _listData; 16 + List<ListenEntity?> _listData = [];
  17 + List<ListenEntity?> get listData => _listData;
18 18
19 ListenBloc() : super(ListenInitial()) { 19 ListenBloc() : super(ListenInitial()) {
20 - on<ListenEvent>((event, emit) {  
21 - // TODO: implement event handler  
22 - }); 20 + on<RequestDataEvent>(_requestData);
23 } 21 }
24 22
25 - Future<void> requestData() async { 23 +
  24 + void _requestData(RequestDataEvent event,Emitter<ListenState> emitter) async {
26 try { 25 try {
27 await loading(() async { 26 await loading(() async {
28 _listData = await ListenDao.listen()??[]; 27 _listData = await ListenDao.listen()??[];
29 - emit(RequestListenDataState()); 28 + emitter(RequestListenDataState());
30 }); 29 });
31 } catch (e) { 30 } catch (e) {
32 if (e is ApiException) { 31 if (e is ApiException) {
lib/pages/listen/bloc/listen_event.dart
@@ -2,3 +2,5 @@ part of &#39;listen_bloc.dart&#39;; @@ -2,3 +2,5 @@ part of &#39;listen_bloc.dart&#39;;
2 2
3 @immutable 3 @immutable
4 abstract class ListenEvent {} 4 abstract class ListenEvent {}
  5 +
  6 +class RequestDataEvent extends ListenEvent {}
lib/pages/listen/listen_page.dart
@@ -13,7 +13,7 @@ class ListenPage extends StatelessWidget { @@ -13,7 +13,7 @@ class ListenPage extends StatelessWidget {
13 @override 13 @override
14 Widget build(BuildContext context) { 14 Widget build(BuildContext context) {
15 return BlocProvider( 15 return BlocProvider(
16 - create: (context) => ListenBloc()..requestData(), 16 + create: (context) => ListenBloc()..add(RequestDataEvent()),
17 child: _ListenPageView(), 17 child: _ListenPageView(),
18 ); 18 );
19 } 19 }
@@ -40,14 +40,15 @@ class _ListenPageView extends StatelessWidget { @@ -40,14 +40,15 @@ class _ListenPageView extends StatelessWidget {
40 builder: (context, state) { 40 builder: (context, state) {
41 final bloc = BlocProvider.of<ListenBloc>(context); 41 final bloc = BlocProvider.of<ListenBloc>(context);
42 return ListView.builder( 42 return ListView.builder(
43 - itemCount: bloc.listData?.length, 43 + itemCount: bloc.listData.length,
44 scrollDirection: Axis.horizontal, 44 scrollDirection: Axis.horizontal,
45 padding: EdgeInsets.symmetric(horizontal: 30.w,vertical: 36.h), 45 padding: EdgeInsets.symmetric(horizontal: 30.w,vertical: 36.h),
46 itemBuilder: (BuildContext context,int index){ 46 itemBuilder: (BuildContext context,int index){
  47 + final entity = bloc.listData[index];
47 return ListenItemWidget( 48 return ListenItemWidget(
48 - entity: bloc.listData?[index], 49 + entity: entity,
49 clickEvent: (){ 50 clickEvent: (){
50 - Navigator.of(context).pushNamed(AppRouteName.lookVideo,arguments: {'videoUrl':'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/7194236f31b2e1e3da0fe06cfed4ba2b.mp4'}); 51 + Navigator.of(context).pushNamed(AppRouteName.lookVideo,arguments: {'videoUrl':entity?.videoUrl,'title':'listen'});
51 }); 52 });
52 }); 53 });
53 }); 54 });
lib/pages/listen/widgets/listen_item_widget.dart
1 -import 'package:cached_network_image/cached_network_image.dart';  
2 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
3 import 'package:flutter_screenutil/flutter_screenutil.dart'; 2 import 'package:flutter_screenutil/flutter_screenutil.dart';
4 import 'package:wow_english/common/extension/string_extension.dart'; 3 import 'package:wow_english/common/extension/string_extension.dart';
lib/pages/practice/chosetopic/topicpicture/bloc/topic_picture_bloc.dart renamed to lib/pages/practice/bloc/topic_picture_bloc.dart
lib/pages/practice/chosetopic/topicpicture/bloc/topic_picture_event.dart renamed to lib/pages/practice/bloc/topic_picture_event.dart
lib/pages/practice/chosetopic/topicpicture/bloc/topic_picture_state.dart renamed to lib/pages/practice/bloc/topic_picture_state.dart
lib/pages/practice/chosetopic/topicpicture/topic_picture_page.dart deleted
1 -import 'package:flutter/material.dart';  
2 -import 'package:flutter_bloc/flutter_bloc.dart';  
3 -import 'package:flutter_screenutil/flutter_screenutil.dart';  
4 -import 'package:wow_english/common/extension/string_extension.dart';  
5 -  
6 -import '../../widgets/practice_header_widget.dart';  
7 -import 'bloc/topic_picture_bloc.dart';  
8 -  
9 -class TopicPicturePage extends StatelessWidget {  
10 - const TopicPicturePage({super.key});  
11 -  
12 - @override  
13 - Widget build(BuildContext context) {  
14 - return BlocProvider(  
15 - create: (context) => TopicPictureBloc(PageController(),3),  
16 - child: _TopicPicturePage(),  
17 - );  
18 - }  
19 -}  
20 -  
21 -class _TopicPicturePage extends StatelessWidget {  
22 - @override  
23 - Widget build(BuildContext context) {  
24 - return BlocListener<TopicPictureBloc,TopicPictureState>(  
25 - listener: (context, state){},  
26 - child: _topicPictureView(),  
27 - );  
28 - }  
29 -  
30 - Widget _topicPictureView() => BlocBuilder<TopicPictureBloc,TopicPictureState>(  
31 - buildWhen: (_,s) => s is CurrentPageIndexState,  
32 - builder: (context,state){  
33 - final bloc = BlocProvider.of<TopicPictureBloc>(context);  
34 - return Container(  
35 - color: Colors.white,  
36 - child: Stack(  
37 - children: [  
38 - Column(  
39 - children: [  
40 - PracticeHeaderWidget(  
41 - title: '${bloc.currentPage}/8',  
42 - onTap: (){Navigator.pop(context);},  
43 - ),  
44 - Expanded(  
45 - child: PageView.builder(  
46 - itemCount: 8,  
47 - scrollDirection: Axis.horizontal,  
48 - controller: bloc.pageController,  
49 - onPageChanged: (int index) {  
50 - bloc.add(CurrentPageIndexChangeEvent(index));  
51 - },  
52 - itemBuilder: (BuildContext context,int index){  
53 - return _pageViewItemWidget();  
54 - }),  
55 - )  
56 - ],  
57 - ),  
58 - Positioned(  
59 - left: 0,  
60 - right: 0,  
61 - bottom: 0,  
62 - child: Image.asset('bottom_grass'.assetPng)  
63 - )  
64 - ],  
65 - ),  
66 - );  
67 - });  
68 -  
69 - Widget _pageViewItemWidget() => BlocBuilder<TopicPictureBloc,TopicPictureState>(  
70 - builder: (context, state){  
71 - final bloc = BlocProvider.of<TopicPictureBloc>(context);  
72 - return SafeArea(  
73 - child: Column(  
74 - children: [  
75 - Text(  
76 - 'What to do when the sentence question is very long and needs a line break',  
77 - softWrap: true,  
78 - style: TextStyle(  
79 - fontSize: 21.sp,  
80 - color: const Color(0xFF333333)  
81 - )  
82 - ),  
83 - 26.verticalSpace,  
84 - Row(  
85 - mainAxisAlignment: MainAxisAlignment.center,  
86 - children: [  
87 - Offstage(  
88 - offstage: (bloc.modelCount < 1),  
89 - child: _decodeImageWidget(1),  
90 - ),  
91 - Offstage(  
92 - offstage: (bloc.modelCount < 2),  
93 - child: _decodeImageWidget(2),  
94 - ),  
95 - Offstage(  
96 - offstage: (bloc.modelCount < 3),  
97 - child: _decodeImageWidget(3),  
98 - ),  
99 - Offstage(  
100 - offstage: (bloc.modelCount < 4),  
101 - child: _decodeImageWidget(4),  
102 - )  
103 - ],  
104 - )  
105 - ],  
106 - ),  
107 - );  
108 - });  
109 -  
110 - Widget _decodeImageWidget(int index) => BlocBuilder<TopicPictureBloc,TopicPictureState>(  
111 - buildWhen: (_, s) => s is SelectItemChangeState,  
112 - builder: (context,state){  
113 - final bloc = BlocProvider.of<TopicPictureBloc>(context);  
114 - return GestureDetector(  
115 - onTap: () => bloc.add(SelectItemEvent(index)),  
116 - child: Container(  
117 - padding: const EdgeInsets.all(4.5),  
118 - decoration: BoxDecoration(  
119 - color: bloc.selectItem == index?const Color(0xFF00B6F1):Colors.white,  
120 - borderRadius: BorderRadius.circular(15),  
121 - ),  
122 - height: 143.h,  
123 - width: 143.w,  
124 - child: Container(  
125 - decoration: BoxDecoration(  
126 - color: Colors.white,  
127 - borderRadius: BorderRadius.circular(15),  
128 - border: Border.all(  
129 - width: 1.0,  
130 - color: const Color(0xFF140C10)  
131 - ),  
132 - image: const DecorationImage(  
133 - fit: BoxFit.fitWidth,  
134 - image: NetworkImage('https://img1.baidu.com/it/u=3392591833,1640391553&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=714')  
135 - )  
136 - ),  
137 - ),  
138 - ),  
139 - );  
140 - });  
141 -}  
142 \ No newline at end of file 0 \ No newline at end of file
lib/pages/practice/chosetopic/topicword/bloc/topic_word_bloc.dart deleted
1 -  
2 -import 'package:flutter/cupertino.dart';  
3 -import 'package:flutter_bloc/flutter_bloc.dart';  
4 -  
5 -part 'topic_word_event.dart';  
6 -part 'topic_word_state.dart';  
7 -  
8 -class TopicWordBloc extends Bloc<TopicWordEvent, TopicWordState> {  
9 - final PageController pageController;  
10 -  
11 - final int modelCount;  
12 -  
13 - int _currentPage = 0;  
14 -  
15 - int _selectItem = 0;  
16 -  
17 - int get currentPage => _currentPage + 1;  
18 -  
19 - int get selectItem => _selectItem;  
20 -  
21 - TopicWordBloc(this.pageController, this.modelCount) : super(TopicWordInitial()) {  
22 - on<CurrentPageIndexChangeEvent>(_pageControllerChange);  
23 - on<SelectItemEvent>(_selectItemLoad);  
24 - }  
25 -  
26 - @override  
27 - Future<void> close() {  
28 - pageController.dispose();  
29 - return super.close();  
30 - }  
31 -  
32 - void _pageControllerChange(CurrentPageIndexChangeEvent event,Emitter<TopicWordState> emitter) async {  
33 - _currentPage = event.pageIndex;  
34 - emitter(CurrentPageIndexState());  
35 - }  
36 -  
37 - void _selectItemLoad(SelectItemEvent event,Emitter<TopicWordState> emitter) async {  
38 - _selectItem = event.selectIndex;  
39 - emitter(SelectItemChangeState());  
40 - }  
41 -}  
lib/pages/practice/chosetopic/topicword/bloc/topic_word_event.dart deleted
1 -part of 'topic_word_bloc.dart';  
2 -  
3 -@immutable  
4 -abstract class TopicWordEvent {}  
5 -  
6 -class CurrentPageIndexChangeEvent extends TopicWordEvent {  
7 - final int pageIndex;  
8 - CurrentPageIndexChangeEvent(this.pageIndex);  
9 -}  
10 -  
11 -class SelectItemEvent extends TopicWordEvent {  
12 - final int selectIndex;  
13 - SelectItemEvent(this.selectIndex);  
14 -}  
15 \ No newline at end of file 0 \ No newline at end of file
lib/pages/practice/chosetopic/topicword/bloc/topic_word_state.dart deleted
1 -part of 'topic_word_bloc.dart';  
2 -  
3 -@immutable  
4 -abstract class TopicWordState {}  
5 -  
6 -class TopicWordInitial extends TopicWordState {}  
7 -  
8 -class CurrentPageIndexState extends TopicWordState {}  
9 -  
10 -class SelectItemChangeState extends TopicWordState {}  
11 \ No newline at end of file 0 \ No newline at end of file
lib/pages/practice/chosetopic/topicword/topic_word_page.dart deleted
1 -import 'package:flutter/material.dart';  
2 -import 'package:flutter_bloc/flutter_bloc.dart';  
3 -import 'package:flutter_screenutil/flutter_screenutil.dart';  
4 -import 'package:wow_english/common/extension/string_extension.dart';  
5 -import 'package:wow_english/pages/practice/widgets/practice_header_widget.dart';  
6 -  
7 -import 'bloc/topic_word_bloc.dart';  
8 -  
9 -class TopicWordPage extends StatelessWidget {  
10 - const TopicWordPage({super.key});  
11 -  
12 - @override  
13 - Widget build(BuildContext context) {  
14 - return BlocProvider(  
15 - create: (context) => TopicWordBloc(PageController(), 4),  
16 - child: _TopicWordPage(),  
17 - );  
18 - }  
19 -}  
20 -  
21 -class _TopicWordPage extends StatelessWidget {  
22 - @override  
23 - Widget build(BuildContext context) {  
24 - return BlocListener<TopicWordBloc,TopicWordState>(  
25 - listener: (context, state) {  
26 -  
27 - },  
28 - child: _topicWordView(),  
29 - );  
30 - }  
31 -  
32 - Widget _topicWordView() => BlocBuilder<TopicWordBloc,TopicWordState>(  
33 - builder: (context,state){  
34 - final bloc = BlocProvider.of<TopicWordBloc>(context);  
35 - return Container(  
36 - color: Colors.white,  
37 - child: Stack(  
38 - children: [  
39 - Positioned(  
40 - left: 0,  
41 - right: 0,  
42 - bottom: 0,  
43 - child: Image.asset('background_grass'.assetPng,fit: BoxFit.fitWidth,)  
44 - ),  
45 - Column(  
46 - children: [  
47 - PracticeHeaderWidget(  
48 - title: '${bloc.currentPage}/8',  
49 - onTap: (){Navigator.pop(context);},  
50 - ),  
51 - Expanded(  
52 - child: PageView.builder(  
53 - itemCount: 8,  
54 - scrollDirection: Axis.horizontal,  
55 - controller: bloc.pageController,  
56 - onPageChanged: (int index) {  
57 - bloc.add(CurrentPageIndexChangeEvent(index));  
58 - },  
59 - itemBuilder: (BuildContext context,int index){  
60 - return _pageViewItemWidget();  
61 - }),  
62 - )  
63 - ],  
64 - ),  
65 - ],  
66 - ),  
67 - );  
68 - });  
69 -  
70 - Widget _pageViewItemWidget() => BlocBuilder<TopicWordBloc,TopicWordState>(  
71 - builder: (context, state){  
72 - final bloc = BlocProvider.of<TopicWordBloc>(context);  
73 - return SafeArea(  
74 - child: Column(  
75 - children: [  
76 - Text(  
77 - 'What to do when the sentence question is very long and needs a line break',  
78 - softWrap: true,  
79 - style: TextStyle(  
80 - fontSize: 21.sp,  
81 - color: const Color(0xFF333333)  
82 - )  
83 - ),  
84 - 26.verticalSpace,  
85 - Row(  
86 - mainAxisAlignment: MainAxisAlignment.spaceBetween,  
87 - children: [  
88 - Offstage(  
89 - offstage: (bloc.modelCount < 1),  
90 - child: _decodeImageWidget(1),  
91 - ),  
92 - Offstage(  
93 - offstage: (bloc.modelCount < 2),  
94 - child: _decodeImageWidget(2),  
95 - ),  
96 - Offstage(  
97 - offstage: (bloc.modelCount < 3),  
98 - child: _decodeImageWidget(3),  
99 - ),  
100 - Offstage(  
101 - offstage: (bloc.modelCount < 4),  
102 - child: _decodeImageWidget(4),  
103 - )  
104 - ],  
105 - )  
106 - ],  
107 - ),  
108 - );  
109 - });  
110 -  
111 - Widget _decodeImageWidget(int index) => BlocBuilder<TopicWordBloc,TopicWordState>(  
112 - buildWhen: (_, s) => s is SelectItemChangeState,  
113 - builder: (context,state){  
114 - final bloc = BlocProvider.of<TopicWordBloc>(context);  
115 - return GestureDetector(  
116 - onTap: () => bloc.add(SelectItemEvent(index)),  
117 - child: Container(  
118 - width: 143.w,  
119 - height: 143.h,  
120 - padding: EdgeInsets.only(left: 13.w,right: 13.w,top: 13.h,bottom: 13.h),  
121 - decoration: BoxDecoration(  
122 - color: Colors.white,  
123 - borderRadius: BorderRadius.circular(15),  
124 - border: Border.all(  
125 - width: 1.0,  
126 - color: const Color(0xFF140C10)  
127 - ),  
128 - ),  
129 - child: Column(  
130 - mainAxisAlignment: MainAxisAlignment.end,  
131 - children: [  
132 - Expanded(  
133 - child: Container(  
134 - alignment: Alignment.center,  
135 - child: Text(  
136 - 'yellow',  
137 - style: TextStyle(  
138 - fontSize: 20.sp,  
139 - color: const Color(0xFF333333)  
140 - )  
141 - ),  
142 - ),  
143 - ),  
144 - Container(  
145 - height: 30.h,  
146 - width: double.infinity,  
147 - decoration: BoxDecoration(  
148 - color: bloc.selectItem == index?const Color(0xFF00B6F1):Colors.white,  
149 - borderRadius: BorderRadius.circular(15.r),  
150 - border: Border.all(  
151 - width: 1.5,  
152 - color: const Color(0xFF140C10)  
153 - ),  
154 - ),  
155 - alignment: Alignment.center,  
156 - child: Image.asset('choose'.assetPng),  
157 - )  
158 - ],  
159 - ),  
160 - ),  
161 - );  
162 - });  
163 -}  
164 \ No newline at end of file 0 \ No newline at end of file
lib/pages/practice/topic_picture_page.dart 0 → 100644
  1 +import 'package:flutter/material.dart';
  2 +import 'package:flutter_bloc/flutter_bloc.dart';
  3 +import 'package:flutter_screenutil/flutter_screenutil.dart';
  4 +import 'package:wow_english/common/extension/string_extension.dart';
  5 +import 'package:wow_english/common/widgets/ow_image_widget.dart';
  6 +
  7 +import 'bloc/topic_picture_bloc.dart';
  8 +import 'widgets/practice_header_widget.dart';
  9 +
  10 +class TopicPicturePage extends StatelessWidget {
  11 + const TopicPicturePage({super.key});
  12 +
  13 + @override
  14 + Widget build(BuildContext context) {
  15 + return BlocProvider(
  16 + create: (context) => TopicPictureBloc(PageController(),3),
  17 + child: _TopicPicturePage(),
  18 + );
  19 + }
  20 +}
  21 +
  22 +class _TopicPicturePage extends StatelessWidget {
  23 + @override
  24 + Widget build(BuildContext context) {
  25 + return BlocListener<TopicPictureBloc,TopicPictureState>(
  26 + listener: (context, state){},
  27 + child: _topicPictureView(),
  28 + );
  29 + }
  30 +
  31 + Widget _topicPictureView() => BlocBuilder<TopicPictureBloc,TopicPictureState>(
  32 + buildWhen: (_,s) => s is CurrentPageIndexState,
  33 + builder: (context,state){
  34 + final bloc = BlocProvider.of<TopicPictureBloc>(context);
  35 + return Container(
  36 + color: Colors.white,
  37 + child: Stack(
  38 + children: [
  39 + Column(
  40 + children: [
  41 + PracticeHeaderWidget(
  42 + title: '${bloc.currentPage}/8',
  43 + onTap: (){Navigator.pop(context);},
  44 + ),
  45 + Expanded(
  46 + child: PageView.builder(
  47 + itemCount: 8,
  48 + scrollDirection: Axis.horizontal,
  49 + controller: bloc.pageController,
  50 + onPageChanged: (int index) {
  51 + bloc.add(CurrentPageIndexChangeEvent(index));
  52 + },
  53 + itemBuilder: (BuildContext context,int index){
  54 + if (index % 5 == 0) {
  55 + return _pageViewWordItemWidget();
  56 + } else if (index % 5 == 1) {
  57 + return _pageViewItemWidget();
  58 + } else if (index % 5 == 2){
  59 + return _pageViewVoicePictureItemWidget();
  60 + } else if (index % 5 == 3){
  61 + return _voiceAnswerItem();
  62 + } else {
  63 + return _pageViewVoiceWordItemWidget();
  64 + }
  65 + }),
  66 + )
  67 + ],
  68 + ),
  69 + Positioned(
  70 + left: 0,
  71 + right: 0,
  72 + bottom: 0,
  73 + child: Image.asset('bottom_grass'.assetPng)
  74 + )
  75 + ],
  76 + ),
  77 + );
  78 + });
  79 +
  80 + ///看题选图
  81 + Widget _pageViewItemWidget() => BlocBuilder<TopicPictureBloc,TopicPictureState>(
  82 + builder: (context, state){
  83 + final bloc = BlocProvider.of<TopicPictureBloc>(context);
  84 + return SafeArea(
  85 + child: Column(
  86 + children: [
  87 + Text(
  88 + 'What to do when the sentence question is very long and needs a line break',
  89 + softWrap: true,
  90 + style: TextStyle(
  91 + fontSize: 21.sp,
  92 + color: const Color(0xFF333333)
  93 + )
  94 + ),
  95 + 26.verticalSpace,
  96 + Row(
  97 + mainAxisAlignment: MainAxisAlignment.center,
  98 + children: [
  99 + Offstage(
  100 + offstage: (bloc.modelCount < 1),
  101 + child: _decodeImageWidget(1),
  102 + ),
  103 + Offstage(
  104 + offstage: (bloc.modelCount < 2),
  105 + child: _decodeImageWidget(2),
  106 + ),
  107 + Offstage(
  108 + offstage: (bloc.modelCount < 3),
  109 + child: _decodeImageWidget(3),
  110 + ),
  111 + Offstage(
  112 + offstage: (bloc.modelCount < 4),
  113 + child: _decodeImageWidget(4),
  114 + )
  115 + ],
  116 + )
  117 + ],
  118 + ),
  119 + );
  120 + });
  121 +
  122 + Widget _decodeImageWidget(int index) => BlocBuilder<TopicPictureBloc,TopicPictureState>(
  123 + buildWhen: (_, s) => s is SelectItemChangeState,
  124 + builder: (context,state){
  125 + final bloc = BlocProvider.of<TopicPictureBloc>(context);
  126 + return GestureDetector(
  127 + onTap: () => bloc.add(SelectItemEvent(index)),
  128 + child: Container(
  129 + padding: const EdgeInsets.all(4.5),
  130 + decoration: BoxDecoration(
  131 + color: bloc.selectItem == index?const Color(0xFF00B6F1):Colors.white,
  132 + borderRadius: BorderRadius.circular(15),
  133 + ),
  134 + height: 143.h,
  135 + width: 143.w,
  136 + child: Container(
  137 + decoration: BoxDecoration(
  138 + color: Colors.white,
  139 + borderRadius: BorderRadius.circular(15),
  140 + border: Border.all(
  141 + width: 1.0,
  142 + color: const Color(0xFF140C10)
  143 + ),
  144 + image: const DecorationImage(
  145 + fit: BoxFit.fitWidth,
  146 + image: NetworkImage('https://img1.baidu.com/it/u=3392591833,1640391553&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=714')
  147 + )
  148 + ),
  149 + ),
  150 + ),
  151 + );
  152 + });
  153 +
  154 + ///看题选字
  155 + Widget _pageViewWordItemWidget() => BlocBuilder<TopicPictureBloc,TopicPictureState>(
  156 + builder: (context, state){
  157 + final bloc = BlocProvider.of<TopicPictureBloc>(context);
  158 + return SafeArea(
  159 + child: Column(
  160 + children: [
  161 + Text(
  162 + 'What to do when the sentence question is very long and needs a line break',
  163 + softWrap: true,
  164 + style: TextStyle(
  165 + fontSize: 21.sp,
  166 + color: const Color(0xFF333333)
  167 + )
  168 + ),
  169 + 26.verticalSpace,
  170 + Row(
  171 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
  172 + children: [
  173 + Offstage(
  174 + offstage: (bloc.modelCount < 1),
  175 + child: _decodeWordWidget(1),
  176 + ),
  177 + Offstage(
  178 + offstage: (bloc.modelCount < 2),
  179 + child: _decodeWordWidget(2),
  180 + ),
  181 + Offstage(
  182 + offstage: (bloc.modelCount < 3),
  183 + child: _decodeWordWidget(3),
  184 + ),
  185 + Offstage(
  186 + offstage: (bloc.modelCount < 4),
  187 + child: _decodeWordWidget(4),
  188 + )
  189 + ],
  190 + )
  191 + ],
  192 + ),
  193 + );
  194 + });
  195 +
  196 + Widget _decodeWordWidget(int index) => BlocBuilder<TopicPictureBloc,TopicPictureState>(
  197 + buildWhen: (_, s) => s is SelectItemChangeState,
  198 + builder: (context,state){
  199 + final bloc = BlocProvider.of<TopicPictureBloc>(context);
  200 + return GestureDetector(
  201 + onTap: () => bloc.add(SelectItemEvent(index)),
  202 + child: Container(
  203 + width: 143.w,
  204 + height: 143.h,
  205 + padding: EdgeInsets.only(left: 13.w,right: 13.w,top: 13.h,bottom: 13.h),
  206 + decoration: BoxDecoration(
  207 + color: Colors.white,
  208 + borderRadius: BorderRadius.circular(15),
  209 + border: Border.all(
  210 + width: 1.0,
  211 + color: const Color(0xFF140C10)
  212 + ),
  213 + ),
  214 + child: Column(
  215 + mainAxisAlignment: MainAxisAlignment.end,
  216 + children: [
  217 + Expanded(
  218 + child: Container(
  219 + alignment: Alignment.center,
  220 + child: Text(
  221 + 'yellow',
  222 + style: TextStyle(
  223 + fontSize: 20.sp,
  224 + color: const Color(0xFF333333)
  225 + )
  226 + ),
  227 + ),
  228 + ),
  229 + Container(
  230 + height: 30.h,
  231 + width: double.infinity,
  232 + decoration: BoxDecoration(
  233 + color: bloc.selectItem == index?const Color(0xFF00B6F1):Colors.white,
  234 + borderRadius: BorderRadius.circular(15.r),
  235 + border: Border.all(
  236 + width: 1.5,
  237 + color: const Color(0xFF140C10)
  238 + ),
  239 + ),
  240 + alignment: Alignment.center,
  241 + child: Image.asset('choose'.assetPng),
  242 + )
  243 + ],
  244 + ),
  245 + ),
  246 + );
  247 + });
  248 +
  249 + ///听音选图
  250 + Widget _pageViewVoicePictureItemWidget() => BlocBuilder<TopicPictureBloc,TopicPictureState>(
  251 + builder: (context, state){
  252 + final bloc = BlocProvider.of<TopicPictureBloc>(context);
  253 + return SafeArea(
  254 + child: Column(
  255 + children: [
  256 + Row(
  257 + mainAxisAlignment: MainAxisAlignment.center,
  258 + children: [
  259 + Image.asset('voice'.assetPng,height: 33.h,width: 30.w,),
  260 + 10.horizontalSpace,
  261 + Text(
  262 + 'yellow',
  263 + style: TextStyle(
  264 + fontSize: 20.sp,
  265 + color: const Color(0xFF333333)
  266 + )
  267 + )
  268 + ],
  269 + ),
  270 + 26.verticalSpace,
  271 + Row(
  272 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
  273 + children: [
  274 + Offstage(
  275 + offstage: (bloc.modelCount < 1),
  276 + child: _decodeVoiceImageWidget(1),
  277 + ),
  278 + Offstage(
  279 + offstage: (bloc.modelCount < 2),
  280 + child: _decodeVoiceImageWidget(2),
  281 + ),
  282 + Offstage(
  283 + offstage: (bloc.modelCount < 3),
  284 + child: _decodeVoiceImageWidget(3),
  285 + ),
  286 + Offstage(
  287 + offstage: (bloc.modelCount < 4),
  288 + child: _decodeVoiceImageWidget(4),
  289 + )
  290 + ],
  291 + )
  292 + ],
  293 + ),
  294 + );
  295 + });
  296 +
  297 + Widget _decodeVoiceImageWidget(int index) => BlocBuilder<TopicPictureBloc,TopicPictureState>(
  298 + buildWhen: (_, s) => s is SelectItemChangeState,
  299 + builder: (context,state){
  300 + final bloc = BlocProvider.of<TopicPictureBloc>(context);
  301 + return GestureDetector(
  302 + onTap: () => bloc.add(SelectItemEvent(index)),
  303 + child: Container(
  304 + padding: const EdgeInsets.all(4.5),
  305 + decoration: BoxDecoration(
  306 + color: bloc.selectItem == index?const Color(0xFF00B6F1):Colors.white,
  307 + borderRadius: BorderRadius.circular(15),
  308 + ),
  309 + height: 143.h,
  310 + width: 143.w,
  311 + child: Container(
  312 + decoration: BoxDecoration(
  313 + color: Colors.white,
  314 + borderRadius: BorderRadius.circular(15),
  315 + border: Border.all(
  316 + width: 1.0,
  317 + color: const Color(0xFF140C10)
  318 + ),
  319 + image: const DecorationImage(
  320 + fit: BoxFit.fitWidth,
  321 + image: NetworkImage('https://img1.baidu.com/it/u=3392591833,1640391553&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=714')
  322 + )
  323 + ),
  324 + ),
  325 + ),
  326 + );
  327 + });
  328 +
  329 + ///听音选字
  330 + Widget _pageViewVoiceWordItemWidget() => BlocBuilder<TopicPictureBloc,TopicPictureState>(
  331 + builder: (context, state){
  332 + final bloc = BlocProvider.of<TopicPictureBloc>(context);
  333 + return SafeArea(
  334 + child: Column(
  335 + children: [
  336 + Image.asset('voice'.assetPng,height: 33.h,width: 30.w,),
  337 + 26.verticalSpace,
  338 + Row(
  339 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
  340 + children: [
  341 + Offstage(
  342 + offstage: (bloc.modelCount < 1),
  343 + child: _decodeVoiceWordImageWidget(1),
  344 + ),
  345 + Offstage(
  346 + offstage: (bloc.modelCount < 2),
  347 + child: _decodeVoiceWordImageWidget(2),
  348 + ),
  349 + Offstage(
  350 + offstage: (bloc.modelCount < 3),
  351 + child: _decodeVoiceWordImageWidget(3),
  352 + ),
  353 + Offstage(
  354 + offstage: (bloc.modelCount < 4),
  355 + child: _decodeVoiceWordImageWidget(4),
  356 + )
  357 + ],
  358 + )
  359 + ],
  360 + ),
  361 + );
  362 + });
  363 +
  364 + Widget _decodeVoiceWordImageWidget(int index) => BlocBuilder<TopicPictureBloc,TopicPictureState>(
  365 + buildWhen: (_, s) => s is SelectItemChangeState,
  366 + builder: (context,state){
  367 + final bloc = BlocProvider.of<TopicPictureBloc>(context);
  368 + return GestureDetector(
  369 + onTap: () => bloc.add(SelectItemEvent(index)),
  370 + child: Container(
  371 + width: 143.w,
  372 + height: 143.h,
  373 + padding: EdgeInsets.only(left: 13.w,right: 13.w,top: 13.h,bottom: 13.h),
  374 + decoration: BoxDecoration(
  375 + color: Colors.white,
  376 + borderRadius: BorderRadius.circular(15),
  377 + border: Border.all(
  378 + width: 1.0,
  379 + color: const Color(0xFF140C10)
  380 + ),
  381 + ),
  382 + child: Column(
  383 + mainAxisAlignment: MainAxisAlignment.end,
  384 + children: [
  385 + Expanded(
  386 + child: Container(
  387 + alignment: Alignment.center,
  388 + child: Text(
  389 + 'yellow',
  390 + style: TextStyle(
  391 + fontSize: 20.sp,
  392 + color: const Color(0xFF333333)
  393 + )
  394 + ),
  395 + ),
  396 + ),
  397 + Container(
  398 + height: 30.h,
  399 + width: double.infinity,
  400 + decoration: BoxDecoration(
  401 + color: bloc.selectItem == index?const Color(0xFF00B6F1):Colors.white,
  402 + borderRadius: BorderRadius.circular(15.r),
  403 + border: Border.all(
  404 + width: 1.5,
  405 + color: const Color(0xFF140C10)
  406 + ),
  407 + ),
  408 + alignment: Alignment.center,
  409 + child: Image.asset('choose'.assetPng),
  410 + )
  411 + ],
  412 + ),
  413 + ),
  414 + );
  415 + });
  416 +
  417 + ///语音问答
  418 + Widget _voiceAnswerItem() => BlocBuilder<TopicPictureBloc,TopicPictureState>(
  419 + builder: (context, state) {
  420 + return Row(
  421 + mainAxisAlignment: MainAxisAlignment.center,
  422 + children: [
  423 + OwImageWidget(
  424 + name:'https://up.enterdesk.com/edpic_source/16/e7/0d/16e70d550daff77cbac31fae5e1651d4.jpg',
  425 + height: 186.h,
  426 + width: 186.w,
  427 + ),
  428 + 160.horizontalSpace,
  429 + Column(
  430 + mainAxisAlignment: MainAxisAlignment.center,
  431 + children: [
  432 + Image.asset(
  433 + 'voice'.assetPng,
  434 + height: 52.h,
  435 + width: 46.w,
  436 + ),
  437 + 70.verticalSpace,
  438 + Image.asset(
  439 + 'micro_phone'.assetPng,
  440 + height: 75.w,
  441 + width: 75.w,
  442 + )
  443 + ],
  444 + )
  445 + ],
  446 + );
  447 + });
  448 +}
0 \ No newline at end of file 449 \ No newline at end of file
lib/pages/practice/voicetopic/voicepicture/bloc/voice_pic_bloc.dart deleted
1 -import 'package:flutter/cupertino.dart';  
2 -import 'package:flutter_bloc/flutter_bloc.dart';  
3 -  
4 -part 'voice_pic_event.dart';  
5 -part 'voice_pic_state.dart';  
6 -  
7 -class VoicePicBloc extends Bloc<VoicePicEvent, VoicePicState> {  
8 - final PageController pageController;  
9 -  
10 - final int modelCount;  
11 -  
12 - int _currentPage = 0;  
13 -  
14 - int _selectItem = 0;  
15 -  
16 - int get currentPage => _currentPage + 1;  
17 -  
18 - int get selectItem => _selectItem;  
19 - VoicePicBloc(this.pageController, this.modelCount) : super(VoicePicInitial()) {  
20 - on<CurrentPageIndexChangeEvent>(_pageControllerChange);  
21 - on<SelectItemEvent>(_selectItemLoad);  
22 - }  
23 -  
24 - @override  
25 - Future<void> close() {  
26 - pageController.dispose();  
27 - return super.close();  
28 - }  
29 -  
30 - void _pageControllerChange(CurrentPageIndexChangeEvent event,Emitter<VoicePicState> emitter) async {  
31 - _currentPage = event.pageIndex;  
32 - emitter(CurrentPageIndexState());  
33 - }  
34 -  
35 - void _selectItemLoad(SelectItemEvent event,Emitter<VoicePicState> emitter) async {  
36 - _selectItem = event.selectIndex;  
37 - emitter(SelectItemChangeState());  
38 - }  
39 -}  
lib/pages/practice/voicetopic/voicepicture/bloc/voice_pic_event.dart deleted
1 -part of 'voice_pic_bloc.dart';  
2 -  
3 -@immutable  
4 -abstract class VoicePicEvent {}  
5 -  
6 -class CurrentPageIndexChangeEvent extends VoicePicEvent {  
7 - final int pageIndex;  
8 - CurrentPageIndexChangeEvent(this.pageIndex);  
9 -}  
10 -  
11 -class SelectItemEvent extends VoicePicEvent {  
12 - final int selectIndex;  
13 - SelectItemEvent(this.selectIndex);  
14 -}  
15 \ No newline at end of file 0 \ No newline at end of file
lib/pages/practice/voicetopic/voicepicture/bloc/voice_pic_state.dart deleted
1 -part of 'voice_pic_bloc.dart';  
2 -  
3 -@immutable  
4 -abstract class VoicePicState {}  
5 -  
6 -class VoicePicInitial extends VoicePicState {}  
7 -  
8 -class CurrentPageIndexState extends VoicePicState {}  
9 -  
10 -class SelectItemChangeState extends VoicePicState {}  
11 \ No newline at end of file 0 \ No newline at end of file
lib/pages/practice/voicetopic/voicepicture/voice_pic_page.dart deleted
1 -import 'package:flutter/material.dart';  
2 -import 'package:flutter_bloc/flutter_bloc.dart';  
3 -import 'package:flutter_screenutil/flutter_screenutil.dart';  
4 -import 'package:wow_english/common/extension/string_extension.dart';  
5 -import 'package:wow_english/pages/practice/widgets/practice_header_widget.dart';  
6 -  
7 -import 'bloc/voice_pic_bloc.dart';  
8 -  
9 -class VoicePicPage extends StatelessWidget {  
10 - const VoicePicPage({super.key});  
11 -  
12 - @override  
13 - Widget build(BuildContext context) {  
14 - return BlocProvider(  
15 - create: (context) => VoicePicBloc(PageController(),4),  
16 - child: _VoicePicPage(),  
17 - );  
18 - }  
19 -}  
20 -  
21 -class _VoicePicPage extends StatelessWidget {  
22 - @override  
23 - Widget build(BuildContext context) {  
24 - return BlocListener<VoicePicBloc, VoicePicState>(  
25 - listener: (context, state){},  
26 - child: _voicePicView(),  
27 - );  
28 - }  
29 -  
30 - Widget _voicePicView() => BlocBuilder<VoicePicBloc, VoicePicState>(  
31 - builder: (context, state){  
32 - return _voicePictureView();  
33 - });  
34 -  
35 - Widget _voicePictureView() => BlocBuilder<VoicePicBloc, VoicePicState>(  
36 - buildWhen: (_,s) => s is CurrentPageIndexState,  
37 - builder: (context,state){  
38 - final bloc = BlocProvider.of<VoicePicBloc>(context);  
39 - return Container(  
40 - color: Colors.white,  
41 - child: Stack(  
42 - children: [  
43 - Image.asset(  
44 - 'road_bg'.assetPng,  
45 - height: double.infinity,  
46 - width: double.infinity  
47 - ),  
48 - Column(  
49 - children: [  
50 - PracticeHeaderWidget(  
51 - title: '${bloc.currentPage}/8',  
52 - onTap: (){Navigator.pop(context);},  
53 - ),  
54 - Row(  
55 - mainAxisAlignment: MainAxisAlignment.center,  
56 - children: [  
57 - Image.asset('voice'.assetPng,height: 33.h,width: 30.w,),  
58 - 10.horizontalSpace,  
59 - Text(  
60 - 'yellow',  
61 - style: TextStyle(  
62 - fontSize: 20.sp,  
63 - color: const Color(0xFF333333)  
64 - )  
65 - )  
66 - ],  
67 - ),  
68 - 26.verticalSpace,  
69 - Expanded(  
70 - child: PageView.builder(  
71 - itemCount: 8,  
72 - scrollDirection: Axis.horizontal,  
73 - controller: bloc.pageController,  
74 - onPageChanged: (int index) {  
75 - bloc.add(CurrentPageIndexChangeEvent(index));  
76 - },  
77 - itemBuilder: (BuildContext context,int index){  
78 - return _pageViewItemWidget();  
79 - }),  
80 - )  
81 - ],  
82 - )  
83 - ],  
84 - ),  
85 - );  
86 - });  
87 -  
88 - Widget _pageViewItemWidget() => BlocBuilder<VoicePicBloc, VoicePicState>(  
89 - builder: (context, state){  
90 - final bloc = BlocProvider.of<VoicePicBloc>(context);  
91 - return SafeArea(  
92 - child: Column(  
93 - children: [  
94 - Row(  
95 - mainAxisAlignment: MainAxisAlignment.spaceBetween,  
96 - children: [  
97 - Offstage(  
98 - offstage: (bloc.modelCount < 1),  
99 - child: _decodeImageWidget(1),  
100 - ),  
101 - Offstage(  
102 - offstage: (bloc.modelCount < 2),  
103 - child: _decodeImageWidget(2),  
104 - ),  
105 - Offstage(  
106 - offstage: (bloc.modelCount < 3),  
107 - child: _decodeImageWidget(3),  
108 - ),  
109 - Offstage(  
110 - offstage: (bloc.modelCount < 4),  
111 - child: _decodeImageWidget(4),  
112 - )  
113 - ],  
114 - )  
115 - ],  
116 - ),  
117 - );  
118 - });  
119 -  
120 - Widget _decodeImageWidget(int index) => BlocBuilder<VoicePicBloc, VoicePicState>(  
121 - buildWhen: (_, s) => s is SelectItemChangeState,  
122 - builder: (context,state){  
123 - final bloc = BlocProvider.of<VoicePicBloc>(context);  
124 - return GestureDetector(  
125 - onTap: () => bloc.add(SelectItemEvent(index)),  
126 - child: Container(  
127 - padding: const EdgeInsets.all(4.5),  
128 - decoration: BoxDecoration(  
129 - color: bloc.selectItem == index?const Color(0xFF00B6F1):Colors.white,  
130 - borderRadius: BorderRadius.circular(15),  
131 - ),  
132 - height: 143.h,  
133 - width: 143.w,  
134 - child: Container(  
135 - decoration: BoxDecoration(  
136 - color: Colors.white,  
137 - borderRadius: BorderRadius.circular(15),  
138 - border: Border.all(  
139 - width: 1.0,  
140 - color: const Color(0xFF140C10)  
141 - ),  
142 - image: const DecorationImage(  
143 - fit: BoxFit.fitWidth,  
144 - image: NetworkImage('https://img1.baidu.com/it/u=3392591833,1640391553&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=714')  
145 - )  
146 - ),  
147 - ),  
148 - ),  
149 - );  
150 - });  
151 -}  
152 \ No newline at end of file 0 \ No newline at end of file
lib/pages/practice/voicetopic/voiceword/bloc/voice_word_bloc.dart deleted
1 -  
2 -import 'package:flutter/cupertino.dart';  
3 -import 'package:flutter_bloc/flutter_bloc.dart';  
4 -  
5 -part 'voice_word_event.dart';  
6 -part 'voice_word_state.dart';  
7 -  
8 -class VoiceWordBloc extends Bloc<VoiceWordEvent, VoiceWordState> {  
9 - final PageController pageController;  
10 -  
11 - final int modelCount;  
12 -  
13 - int _currentPage = 0;  
14 -  
15 - int _selectItem = 0;  
16 -  
17 - int get currentPage => _currentPage + 1;  
18 -  
19 - int get selectItem => _selectItem;  
20 - VoiceWordBloc(this.pageController, this.modelCount) : super(VoiceWordInitial()) {  
21 - on<CurrentPageIndexChangeEvent>(_pageControllerChange);  
22 - on<SelectItemEvent>(_selectItemLoad);  
23 - }  
24 -  
25 - @override  
26 - Future<void> close() {  
27 - pageController.dispose();  
28 - return super.close();  
29 - }  
30 -  
31 - void _pageControllerChange(CurrentPageIndexChangeEvent event,Emitter<VoiceWordState> emitter) async {  
32 - _currentPage = event.pageIndex;  
33 - emitter(CurrentPageIndexState());  
34 - }  
35 -  
36 - void _selectItemLoad(SelectItemEvent event,Emitter<VoiceWordState> emitter) async {  
37 - _selectItem = event.selectIndex;  
38 - emitter(SelectItemChangeState());  
39 - }  
40 -}  
41 -  
lib/pages/practice/voicetopic/voiceword/bloc/voice_word_event.dart deleted
1 -part of 'voice_word_bloc.dart';  
2 -  
3 -@immutable  
4 -abstract class VoiceWordEvent {}  
5 -  
6 -class CurrentPageIndexChangeEvent extends VoiceWordEvent {  
7 - final int pageIndex;  
8 - CurrentPageIndexChangeEvent(this.pageIndex);  
9 -}  
10 -  
11 -class SelectItemEvent extends VoiceWordEvent {  
12 - final int selectIndex;  
13 - SelectItemEvent(this.selectIndex);  
14 -}  
15 \ No newline at end of file 0 \ No newline at end of file
lib/pages/practice/voicetopic/voiceword/bloc/voice_word_state.dart deleted
1 -part of 'voice_word_bloc.dart';  
2 -  
3 -@immutable  
4 -abstract class VoiceWordState {}  
5 -  
6 -class VoiceWordInitial extends VoiceWordState {}  
7 -  
8 -class CurrentPageIndexState extends VoiceWordState {}  
9 -  
10 -class SelectItemChangeState extends VoiceWordState {}  
lib/pages/practice/voicetopic/voiceword/voice_word_page.dart deleted
1 -import 'package:flutter/material.dart';  
2 -import 'package:flutter_bloc/flutter_bloc.dart';  
3 -import 'package:flutter_screenutil/flutter_screenutil.dart';  
4 -import 'package:wow_english/common/extension/string_extension.dart';  
5 -import 'package:wow_english/pages/practice/widgets/practice_header_widget.dart';  
6 -  
7 -import 'bloc/voice_word_bloc.dart';  
8 -  
9 -class VoiceWordPage extends StatelessWidget {  
10 - const VoiceWordPage({super.key});  
11 -  
12 -  
13 - @override  
14 - Widget build(BuildContext context) {  
15 - return BlocProvider(  
16 - create: (context) => VoiceWordBloc(PageController(),4),  
17 - child: _VoiceWordPage(),  
18 - );  
19 - }  
20 -}  
21 -  
22 -class _VoiceWordPage extends StatelessWidget {  
23 - @override  
24 - Widget build(BuildContext context) {  
25 - return BlocListener<VoiceWordBloc, VoiceWordState>(  
26 - listener: (context, state){},  
27 - child: _voiceWorView(),  
28 - );  
29 - }  
30 -  
31 - Widget _voiceWorView() => BlocBuilder<VoiceWordBloc, VoiceWordState>(  
32 - builder: (context, state){  
33 - return _voiceWordView();  
34 - });  
35 -  
36 - Widget _voiceWordView() => BlocBuilder<VoiceWordBloc, VoiceWordState>(  
37 - buildWhen: (_,s) => s is CurrentPageIndexState,  
38 - builder: (context,state){  
39 - final bloc = BlocProvider.of<VoiceWordBloc>(context);  
40 - return Container(  
41 - color: Colors.white,  
42 - child: Stack(  
43 - children: [  
44 - Image.asset(  
45 - 'road_bg'.assetPng,  
46 - height: double.infinity,  
47 - width: double.infinity  
48 - ),  
49 - Column(  
50 - children: [  
51 - PracticeHeaderWidget(  
52 - title: '${bloc.currentPage}/8',  
53 - onTap: (){Navigator.pop(context);},  
54 - ),  
55 - Image.asset('voice'.assetPng,height: 33.h,width: 30.w,),  
56 - 26.verticalSpace,  
57 - Expanded(  
58 - child: PageView.builder(  
59 - itemCount: 8,  
60 - scrollDirection: Axis.horizontal,  
61 - controller: bloc.pageController,  
62 - onPageChanged: (int index) {  
63 - bloc.add(CurrentPageIndexChangeEvent(index));  
64 - },  
65 - itemBuilder: (BuildContext context,int index){  
66 - return _pageViewItemWidget();  
67 - }),  
68 - )  
69 - ],  
70 - )  
71 - ],  
72 - ),  
73 - );  
74 - });  
75 -  
76 - Widget _pageViewItemWidget() => BlocBuilder<VoiceWordBloc, VoiceWordState>(  
77 - builder: (context, state){  
78 - final bloc = BlocProvider.of<VoiceWordBloc>(context);  
79 - return SafeArea(  
80 - child: Column(  
81 - children: [  
82 - Row(  
83 - mainAxisAlignment: MainAxisAlignment.spaceBetween,  
84 - children: [  
85 - Offstage(  
86 - offstage: (bloc.modelCount < 1),  
87 - child: _decodeImageWidget(1),  
88 - ),  
89 - Offstage(  
90 - offstage: (bloc.modelCount < 2),  
91 - child: _decodeImageWidget(2),  
92 - ),  
93 - Offstage(  
94 - offstage: (bloc.modelCount < 3),  
95 - child: _decodeImageWidget(3),  
96 - ),  
97 - Offstage(  
98 - offstage: (bloc.modelCount < 4),  
99 - child: _decodeImageWidget(4),  
100 - )  
101 - ],  
102 - )  
103 - ],  
104 - ),  
105 - );  
106 - });  
107 -  
108 - Widget _decodeImageWidget(int index) => BlocBuilder<VoiceWordBloc,VoiceWordState>(  
109 - buildWhen: (_, s) => s is SelectItemChangeState,  
110 - builder: (context,state){  
111 - final bloc = BlocProvider.of<VoiceWordBloc>(context);  
112 - return GestureDetector(  
113 - onTap: () => bloc.add(SelectItemEvent(index)),  
114 - child: Container(  
115 - width: 143.w,  
116 - height: 143.h,  
117 - padding: EdgeInsets.only(left: 13.w,right: 13.w,top: 13.h,bottom: 13.h),  
118 - decoration: BoxDecoration(  
119 - color: Colors.white,  
120 - borderRadius: BorderRadius.circular(15),  
121 - border: Border.all(  
122 - width: 1.0,  
123 - color: const Color(0xFF140C10)  
124 - ),  
125 - ),  
126 - child: Column(  
127 - mainAxisAlignment: MainAxisAlignment.end,  
128 - children: [  
129 - Expanded(  
130 - child: Container(  
131 - alignment: Alignment.center,  
132 - child: Text(  
133 - 'yellow',  
134 - style: TextStyle(  
135 - fontSize: 20.sp,  
136 - color: const Color(0xFF333333)  
137 - )  
138 - ),  
139 - ),  
140 - ),  
141 - Container(  
142 - height: 30.h,  
143 - width: double.infinity,  
144 - decoration: BoxDecoration(  
145 - color: bloc.selectItem == index?const Color(0xFF00B6F1):Colors.white,  
146 - borderRadius: BorderRadius.circular(15.r),  
147 - border: Border.all(  
148 - width: 1.5,  
149 - color: const Color(0xFF140C10)  
150 - ),  
151 - ),  
152 - alignment: Alignment.center,  
153 - child: Image.asset('choose'.assetPng),  
154 - )  
155 - ],  
156 - ),  
157 - ),  
158 - );  
159 - });  
160 -}  
161 \ No newline at end of file 0 \ No newline at end of file
lib/pages/repeatafter/bloc/repeat_after_bloc.dart
@@ -15,17 +15,15 @@ class RepeatAfterBloc extends Bloc&lt;RepeatAfterEvent, RepeatAfterState&gt; { @@ -15,17 +15,15 @@ class RepeatAfterBloc extends Bloc&lt;RepeatAfterEvent, RepeatAfterState&gt; {
15 List<FollowReadEntity?> get listData => _listData; 15 List<FollowReadEntity?> get listData => _listData;
16 16
17 RepeatAfterBloc() : super(RepeatAfterInitial()) { 17 RepeatAfterBloc() : super(RepeatAfterInitial()) {
18 - on<RepeatAfterEvent>((event, emit) {  
19 - // TODO: implement event handler  
20 - }); 18 + on<RequestDataEvent>(_requestData);
21 } 19 }
22 20
23 21
24 - Future<void> requestData() async { 22 + void _requestData(RequestDataEvent event, Emitter<RepeatAfterState> emitter) async {
25 try { 23 try {
26 await loading(() async { 24 await loading(() async {
27 _listData = await ListenDao.followRead()??[]; 25 _listData = await ListenDao.followRead()??[];
28 - emit(RequestDataState()); 26 + emitter(RequestDataState());
29 }); 27 });
30 } catch (e) { 28 } catch (e) {
31 if (e is ApiException) { 29 if (e is ApiException) {
lib/pages/repeatafter/bloc/repeat_after_event.dart
@@ -2,3 +2,5 @@ part of &#39;repeat_after_bloc.dart&#39;; @@ -2,3 +2,5 @@ part of &#39;repeat_after_bloc.dart&#39;;
2 2
3 @immutable 3 @immutable
4 abstract class RepeatAfterEvent {} 4 abstract class RepeatAfterEvent {}
  5 +
  6 +class RequestDataEvent extends RepeatAfterEvent {}
lib/pages/repeatafter/repeat_after_page.dart
@@ -13,7 +13,7 @@ class RepeatAfterPage extends StatelessWidget { @@ -13,7 +13,7 @@ class RepeatAfterPage extends StatelessWidget {
13 @override 13 @override
14 Widget build(BuildContext context) { 14 Widget build(BuildContext context) {
15 return BlocProvider( 15 return BlocProvider(
16 - create: (context) => RepeatAfterBloc()..requestData(), 16 + create: (context) => RepeatAfterBloc()..add(RequestDataEvent()),
17 child: _RepeatAfterPageView(), 17 child: _RepeatAfterPageView(),
18 ); 18 );
19 } 19 }
lib/pages/video/lookvideo/look_video_page.dart
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
2 -import 'package:flutter_bloc/flutter_bloc.dart';  
3 import 'package:wow_english/pages/video/lookvideo/widgets/video_widget.dart'; 2 import 'package:wow_english/pages/video/lookvideo/widgets/video_widget.dart';
4 3
5 -import 'bloc/look_video_bloc.dart';  
6 -  
7 class LookVideoPage extends StatefulWidget { 4 class LookVideoPage extends StatefulWidget {
8 - const LookVideoPage({super.key, this.videoUrl}); 5 + const LookVideoPage({super.key, this.videoUrl, this.typeTitle});
9 6
10 final String? videoUrl; 7 final String? videoUrl;
  8 + final String? typeTitle;
11 9
12 @override 10 @override
13 State<StatefulWidget> createState() { 11 State<StatefulWidget> createState() {
@@ -20,23 +18,7 @@ class _LookVideoPageState extends State&lt;LookVideoPage&gt; { @@ -20,23 +18,7 @@ class _LookVideoPageState extends State&lt;LookVideoPage&gt; {
20 Widget build(BuildContext context) { 18 Widget build(BuildContext context) {
21 return VideoWidget( 19 return VideoWidget(
22 videoUrl: widget.videoUrl??'', 20 videoUrl: widget.videoUrl??'',
  21 + typeTitle: widget.typeTitle,
23 ); 22 );
24 } 23 }
25 -}  
26 -  
27 -class _LookVideoPage extends StatelessWidget {  
28 - @override  
29 - Widget build(BuildContext context) {  
30 - return BlocListener<LookVideoBloc, LookVideoState>(  
31 - listener: (context,state){},  
32 - child: _lookVideoView(),  
33 - );  
34 - }  
35 -  
36 - Widget _lookVideoView() => BlocBuilder<LookVideoBloc, LookVideoState>(  
37 - builder: (context,state){  
38 - return const VideoWidget(  
39 - videoUrl: 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/7194236f31b2e1e3da0fe06cfed4ba2b.mp4',  
40 - );  
41 - });  
42 } 24 }
43 \ No newline at end of file 25 \ No newline at end of file
lib/pages/video/lookvideo/widgets/video_opera_widget.dart
@@ -20,7 +20,8 @@ class VideoOperaWidget extends StatefulWidget { @@ -20,7 +20,8 @@ class VideoOperaWidget extends StatefulWidget {
20 this.degree = 0.0, 20 this.degree = 0.0,
21 this.actionEvent, 21 this.actionEvent,
22 this.sliderChangeEvent, 22 this.sliderChangeEvent,
23 - this.isPlay = true 23 + this.isPlay = true,
  24 + this.title = 'song',
24 }); 25 });
25 //当前播放时间 26 //当前播放时间
26 final String currentTime; 27 final String currentTime;
@@ -28,6 +29,7 @@ class VideoOperaWidget extends StatefulWidget { @@ -28,6 +29,7 @@ class VideoOperaWidget extends StatefulWidget {
28 final String totalTime; 29 final String totalTime;
29 final double degree; 30 final double degree;
30 final bool isPlay; 31 final bool isPlay;
  32 + final String title;
31 final Function(OperationType type)? actionEvent; 33 final Function(OperationType type)? actionEvent;
32 final Function(double degree)? sliderChangeEvent; 34 final Function(double degree)? sliderChangeEvent;
33 35
@@ -90,7 +92,7 @@ class _VideoOperaWidgetState extends State&lt;VideoOperaWidget&gt; { @@ -90,7 +92,7 @@ class _VideoOperaWidgetState extends State&lt;VideoOperaWidget&gt; {
90 ), 92 ),
91 padding: EdgeInsets.symmetric(horizontal: 10.w), 93 padding: EdgeInsets.symmetric(horizontal: 10.w),
92 child: Text( 94 child: Text(
93 - 'song', 95 + widget.title,
94 textAlign: TextAlign.center, 96 textAlign: TextAlign.center,
95 style: TextStyle( 97 style: TextStyle(
96 fontSize: 20.sp, 98 fontSize: 20.sp,
@@ -100,31 +102,31 @@ class _VideoOperaWidgetState extends State&lt;VideoOperaWidget&gt; { @@ -100,31 +102,31 @@ class _VideoOperaWidgetState extends State&lt;VideoOperaWidget&gt; {
100 ) 102 )
101 ], 103 ],
102 ), 104 ),
103 - GestureDetector(  
104 - onTap: () {  
105 - widget.actionEvent?.call(OperationType.subtitlesState);  
106 - },  
107 - child: Container(  
108 - height: 40.h,  
109 - alignment: Alignment.center,  
110 - decoration: BoxDecoration(  
111 - color: Colors.white,  
112 - borderRadius: BorderRadius.circular(6.r),  
113 - border: Border.all(  
114 - width: 1.5,  
115 - color: const Color(0xFF140C10)  
116 - )  
117 - ),  
118 - padding: EdgeInsets.symmetric(horizontal: 10.w),  
119 - child: Text(  
120 - '中/英',  
121 - style: TextStyle(  
122 - fontSize: 20.sp,  
123 - color: const Color(0xFF333333),  
124 - ),  
125 - ),  
126 - ),  
127 - ) 105 + // GestureDetector(
  106 + // onTap: () {
  107 + // widget.actionEvent?.call(OperationType.subtitlesState);
  108 + // },
  109 + // child: Container(
  110 + // height: 40.h,
  111 + // alignment: Alignment.center,
  112 + // decoration: BoxDecoration(
  113 + // color: Colors.white,
  114 + // borderRadius: BorderRadius.circular(6.r),
  115 + // border: Border.all(
  116 + // width: 1.5,
  117 + // color: const Color(0xFF140C10)
  118 + // )
  119 + // ),
  120 + // padding: EdgeInsets.symmetric(horizontal: 10.w),
  121 + // child: Text(
  122 + // '中/英',
  123 + // style: TextStyle(
  124 + // fontSize: 20.sp,
  125 + // color: const Color(0xFF333333),
  126 + // ),
  127 + // ),
  128 + // ),
  129 + // )
128 ], 130 ],
129 ), 131 ),
130 ), 132 ),
lib/pages/video/lookvideo/widgets/video_widget.dart
@@ -7,9 +7,10 @@ import &#39;package:wow_english/common/extension/string_extension.dart&#39;; @@ -7,9 +7,10 @@ import &#39;package:wow_english/common/extension/string_extension.dart&#39;;
7 import 'video_opera_widget.dart'; 7 import 'video_opera_widget.dart';
8 8
9 class VideoWidget extends StatefulWidget { 9 class VideoWidget extends StatefulWidget {
10 - const VideoWidget({super.key, this.videoUrl = ''}); 10 + const VideoWidget({super.key, this.videoUrl = '',this.typeTitle});
11 11
12 final String videoUrl; 12 final String videoUrl;
  13 + final String? typeTitle;
13 14
14 @override 15 @override
15 State<StatefulWidget> createState() { 16 State<StatefulWidget> createState() {
@@ -53,9 +54,6 @@ class _VideoWidgetState extends State&lt;VideoWidget&gt; { @@ -53,9 +54,6 @@ class _VideoWidgetState extends State&lt;VideoWidget&gt; {
53 timerUtil = TimerUtil(mInterval: 1000,mTotalTime: 1000*10); 54 timerUtil = TimerUtil(mInterval: 1000,mTotalTime: 1000*10);
54 timerUtil!.setOnTimerTickCallback((int tick) { 55 timerUtil!.setOnTimerTickCallback((int tick) {
55 double currentTick = tick / 1000; 56 double currentTick = tick / 1000;
56 - if (kDebugMode) {  
57 - print(currentTick);  
58 - }  
59 if (currentTick.toInt() == 0) {//倒计时结束 57 if (currentTick.toInt() == 0) {//倒计时结束
60 setState(() { 58 setState(() {
61 _hiddenTipView = true; 59 _hiddenTipView = true;
@@ -148,9 +146,10 @@ class _VideoWidgetState extends State&lt;VideoWidget&gt; { @@ -148,9 +146,10 @@ class _VideoWidgetState extends State&lt;VideoWidget&gt; {
148 Offstage( 146 Offstage(
149 offstage: _hiddenTipView, 147 offstage: _hiddenTipView,
150 child: VideoOperaWidget( 148 child: VideoOperaWidget(
151 - currentTime: _currentTime,  
152 - totalTime: _totalTime, 149 + title: widget.typeTitle??'song',
153 degree: _playDegree, 150 degree: _playDegree,
  151 + totalTime: _totalTime,
  152 + currentTime: _currentTime,
154 isPlay: _controller!.value.isPlaying, 153 isPlay: _controller!.value.isPlaying,
155 actionEvent: (OperationType type) { 154 actionEvent: (OperationType type) {
156 actionType(type); 155 actionType(type);
lib/pages/voiceanswer/bloc/voice_answer_bloc.dart deleted
1 -import 'package:flutter/cupertino.dart';  
2 -import 'package:flutter_bloc/flutter_bloc.dart';  
3 -  
4 -part 'voice_answer_event.dart';  
5 -part 'voice_answer_state.dart';  
6 -  
7 -class VoiceAnswerBloc extends Bloc<VoiceAnswerEvent, VoiceAnswerState> {  
8 - VoiceAnswerBloc() : super(VoiceAnswerInitial()) {  
9 - on<VoiceAnswerEvent>((event, emit) {  
10 - // TODO: implement event handler  
11 - });  
12 - }  
13 -}  
lib/pages/voiceanswer/bloc/voice_answer_event.dart deleted
1 -part of 'voice_answer_bloc.dart';  
2 -  
3 -@immutable  
4 -abstract class VoiceAnswerEvent {}  
lib/pages/voiceanswer/bloc/voice_answer_state.dart deleted
1 -part of 'voice_answer_bloc.dart';  
2 -  
3 -@immutable  
4 -abstract class VoiceAnswerState {}  
5 -  
6 -class VoiceAnswerInitial extends VoiceAnswerState {}  
lib/pages/voiceanswer/voice_answer_page.dart deleted
1 -import 'package:flutter/material.dart';  
2 -import 'package:flutter_bloc/flutter_bloc.dart';  
3 -import 'package:flutter_screenutil/flutter_screenutil.dart';  
4 -import 'package:wow_english/common/extension/string_extension.dart';  
5 -import 'package:wow_english/pages/practice/widgets/practice_header_widget.dart';  
6 -  
7 -import 'bloc/voice_answer_bloc.dart';  
8 -  
9 -class VoiceAnswerPage extends StatelessWidget {  
10 - const VoiceAnswerPage({super.key});  
11 -  
12 - @override  
13 - Widget build(BuildContext context) {  
14 - return BlocProvider(  
15 - create: (_) => VoiceAnswerBloc(),  
16 - child: _VoiceAnswerPage(),  
17 - );  
18 - }  
19 -}  
20 -  
21 -class _VoiceAnswerPage extends StatelessWidget {  
22 - @override  
23 - Widget build(BuildContext context) {  
24 - return BlocListener<VoiceAnswerBloc,VoiceAnswerState>(  
25 - listener: (context, state) {},  
26 - child: _voiceAnswerView(),  
27 - );  
28 - }  
29 -  
30 - Widget _voiceAnswerView() => BlocBuilder<VoiceAnswerBloc,VoiceAnswerState>(  
31 - builder: (context, state) {  
32 - final bloc = BlocProvider.of<VoiceAnswerBloc>(context);  
33 - return Container(  
34 - color: Colors.white,  
35 - child: Stack(  
36 - children: [  
37 - Positioned(  
38 - left: 0,  
39 - right: 0,  
40 - bottom: 0,  
41 - child: Image.asset(  
42 - 'bottom_grass'.assetPng,  
43 - fit: BoxFit.fitWidth,  
44 - )),  
45 - Column(  
46 - children: [  
47 - PracticeHeaderWidget(  
48 - title: '1/8',  
49 - onTap: () {  
50 - Navigator.pop(context);  
51 - },  
52 - ),  
53 - Expanded(  
54 - child: PageView.builder(  
55 - itemCount: 10,  
56 - itemBuilder: (context, int index) {  
57 - return _voiceAnswerItem();  
58 - }))  
59 - ],  
60 - )  
61 - ],  
62 - ),  
63 - );  
64 - });  
65 -  
66 - Widget _voiceAnswerItem() => BlocBuilder<VoiceAnswerBloc,VoiceAnswerState>(builder: (context, state) {  
67 - return Row(  
68 - mainAxisAlignment: MainAxisAlignment.center,  
69 - children: [  
70 - Image.network(  
71 - 'https://img.liblibai.com/web/648331d5a2cb5.png?image_process=format,webp&x-oss-process=image/resize,w_2980,m_lfit/format,webp',  
72 - height: 186.h,  
73 - width: 186.w,  
74 - ),  
75 - 160.horizontalSpace,  
76 - Column(  
77 - mainAxisAlignment: MainAxisAlignment.center,  
78 - children: [  
79 - Image.asset(  
80 - 'voice'.assetPng,  
81 - height: 52.h,  
82 - width: 46.w,  
83 - ),  
84 - 70.verticalSpace,  
85 - Image.asset(  
86 - 'micro_phone'.assetPng,  
87 - height: 75.w,  
88 - width: 75.w,  
89 - )  
90 - ],  
91 - )  
92 - ],  
93 - );  
94 - });  
95 -}  
lib/route/route.dart
@@ -8,10 +8,7 @@ import &#39;package:wow_english/pages/listen/listen_page.dart&#39;; @@ -8,10 +8,7 @@ import &#39;package:wow_english/pages/listen/listen_page.dart&#39;;
8 import 'package:wow_english/pages/login/forgetpwd/forget_password_home_page.dart'; 8 import 'package:wow_english/pages/login/forgetpwd/forget_password_home_page.dart';
9 import 'package:wow_english/pages/login/loginpage/login_page.dart'; 9 import 'package:wow_english/pages/login/loginpage/login_page.dart';
10 import 'package:wow_english/pages/login/setpwd/set_pwd_page.dart'; 10 import 'package:wow_english/pages/login/setpwd/set_pwd_page.dart';
11 -import 'package:wow_english/pages/practice/chosetopic/topicpicture/topic_picture_page.dart';  
12 -import 'package:wow_english/pages/practice/chosetopic/topicword/topic_word_page.dart';  
13 -import 'package:wow_english/pages/practice/voicetopic/voicepicture/voice_pic_page.dart';  
14 -import 'package:wow_english/pages/practice/voicetopic/voiceword/voice_word_page.dart'; 11 +import 'package:wow_english/pages/practice/topic_picture_page.dart';
15 import 'package:wow_english/pages/repeatafter/repeat_after_page.dart'; 12 import 'package:wow_english/pages/repeatafter/repeat_after_page.dart';
16 import 'package:wow_english/pages/shop/exchane/exchange_lesson_page.dart'; 13 import 'package:wow_english/pages/shop/exchane/exchange_lesson_page.dart';
17 import 'package:wow_english/pages/shop/exchangelist/exchange_lesson_list_page.dart'; 14 import 'package:wow_english/pages/shop/exchangelist/exchange_lesson_list_page.dart';
@@ -19,7 +16,6 @@ import &#39;package:wow_english/pages/shop/home/shop_home_page.dart&#39;; @@ -19,7 +16,6 @@ import &#39;package:wow_english/pages/shop/home/shop_home_page.dart&#39;;
19 import 'package:wow_english/pages/tab/tab_page.dart'; 16 import 'package:wow_english/pages/tab/tab_page.dart';
20 import 'package:wow_english/pages/user/user_page.dart'; 17 import 'package:wow_english/pages/user/user_page.dart';
21 import 'package:wow_english/pages/video/lookvideo/look_video_page.dart'; 18 import 'package:wow_english/pages/video/lookvideo/look_video_page.dart';
22 -import 'package:wow_english/pages/voiceanswer/voice_answer_page.dart';  
23 19
24 import '../pages/reading/reading_page.dart'; 20 import '../pages/reading/reading_page.dart';
25 21
@@ -87,17 +83,10 @@ class AppRouter { @@ -87,17 +83,10 @@ class AppRouter {
87 return CupertinoPageRoute(builder: (_) => const UserPage()); 83 return CupertinoPageRoute(builder: (_) => const UserPage());
88 case AppRouteName.topicPic: 84 case AppRouteName.topicPic:
89 return CupertinoPageRoute(builder: (_) => const TopicPicturePage()); 85 return CupertinoPageRoute(builder: (_) => const TopicPicturePage());
90 - case AppRouteName.topicWord:  
91 - return CupertinoPageRoute(builder: (_) => const TopicWordPage());  
92 - case AppRouteName.voicePic:  
93 - return CupertinoPageRoute(builder: (_) => const VoicePicPage());  
94 - case AppRouteName.voiceWord:  
95 - return CupertinoPageRoute(builder: (_) => const VoiceWordPage());  
96 - case AppRouteName.voiceAnswer:  
97 - return CupertinoPageRoute(builder: (_) => const VoiceAnswerPage());  
98 case AppRouteName.lookVideo: 86 case AppRouteName.lookVideo:
99 final videoUrl = (settings.arguments as Map)['videoUrl'] as String; 87 final videoUrl = (settings.arguments as Map)['videoUrl'] as String;
100 - return CupertinoPageRoute(builder: (_) => LookVideoPage(videoUrl: videoUrl,)); 88 + final title = (settings.arguments as Map)['title'] as String?;
  89 + return CupertinoPageRoute(builder: (_) => LookVideoPage(videoUrl: videoUrl,typeTitle: title,));
101 case AppRouteName.setPwd: 90 case AppRouteName.setPwd:
102 final phoneNum = (settings.arguments as Map)['phoneNumber'] as String; 91 final phoneNum = (settings.arguments as Map)['phoneNumber'] as String;
103 return CupertinoPageRoute(builder: (_) => SetPassWordPage(phoneNum: phoneNum)); 92 return CupertinoPageRoute(builder: (_) => SetPassWordPage(phoneNum: phoneNum));