Commit 2512b58cfb93b0db16705ff0f2cc99cb6e84b76e

Authored by 吴启风
1 parent 0ebc6186

feat:性能优化-练习页PageView根据是否是当前页来决定build以及SpeakerWidget组件isPlaying

lib/pages/practice/topic_picture_page.dart
@@ -93,28 +93,36 @@ class _TopicPicturePage extends StatelessWidget { @@ -93,28 +93,36 @@ class _TopicPicturePage extends StatelessWidget {
93 bloc.add(CurrentPageIndexChangeEvent(index)); 93 bloc.add(CurrentPageIndexChangeEvent(index));
94 }, 94 },
95 itemBuilder: (BuildContext context, int index) { 95 itemBuilder: (BuildContext context, int index) {
  96 + final bloc =
  97 + BlocProvider.of<TopicPictureBloc>(context);
96 CourseProcessTopics? topics = 98 CourseProcessTopics? topics =
97 bloc.entity?.topics![index]; 99 bloc.entity?.topics![index];
  100 + bool isCurrentPage =
  101 + index == bloc.currentPage - 1;
98 if (topics?.type == 102 if (topics?.type ==
99 TopicType.audioImageSelect.value) { 103 TopicType.audioImageSelect.value) {
100 //听音选图 104 //听音选图
101 return _pageViewVoicePictureItemWidget( 105 return _pageViewVoicePictureItemWidget(
102 - topics); 106 + topics, isCurrentPage);
103 } else if (topics?.type == 107 } else if (topics?.type ==
104 TopicType.audioCharSelect.value) { 108 TopicType.audioCharSelect.value) {
105 //听音选字 109 //听音选字
106 - return _pageViewVoiceWordItemWidget(topics); 110 + return _pageViewVoiceWordItemWidget(
  111 + topics, isCurrentPage);
107 } else if (topics?.type == 112 } else if (topics?.type ==
108 TopicType.questionCharSelect.value) { 113 TopicType.questionCharSelect.value) {
109 //看题选字 114 //看题选字
110 - return _pageViewWordItemWidget(topics); 115 + return _pageViewWordItemWidget(
  116 + topics, isCurrentPage);
111 } else if (topics?.type == 117 } else if (topics?.type ==
112 TopicType.questionImageSelect.value) { 118 TopicType.questionImageSelect.value) {
113 //看题选图 119 //看题选图
114 - return _pageViewItemWidget(topics); 120 + return _pageViewItemWidget(
  121 + topics, isCurrentPage);
115 } else { 122 } else {
116 //语音问答 123 //语音问答
117 - return _voiceAnswerItem(topics); 124 + return _voiceAnswerItem(
  125 + topics, isCurrentPage);
118 } 126 }
119 }), 127 }),
120 ) 128 )
@@ -130,33 +138,34 @@ class _TopicPicturePage extends StatelessWidget { @@ -130,33 +138,34 @@ class _TopicPicturePage extends StatelessWidget {
130 }); 138 });
131 139
132 ///看题选图 140 ///看题选图
133 - Widget _pageViewItemWidget(CourseProcessTopics? topics) => 141 + Widget _pageViewItemWidget(CourseProcessTopics? topics, bool isCurrentPage) =>
134 BlocBuilder<TopicPictureBloc, TopicPictureState>( 142 BlocBuilder<TopicPictureBloc, TopicPictureState>(
  143 + buildWhen: (_, s) => isCurrentPage,
135 builder: (context, state) { 144 builder: (context, state) {
136 - return SafeArea(  
137 - child: Column(  
138 - children: [  
139 - Text(topics?.word ?? '',  
140 - softWrap: true,  
141 - style: TextStyle(  
142 - fontSize: 21.sp, color: const Color(0xFF333333))),  
143 - 26.verticalSpace,  
144 - SizedBox(  
145 - height: 143.h,  
146 - width: 143.w * (topics?.topicAnswerList?.length ?? 0),  
147 - child: ListView.builder(  
148 - scrollDirection: Axis.horizontal,  
149 - physics: const NeverScrollableScrollPhysics(),  
150 - itemCount: topics?.topicAnswerList?.length ?? 0,  
151 - itemBuilder: (context, index) {  
152 - return _decodeImageWidget(  
153 - index, topics?.topicAnswerList?[index]);  
154 - }), 145 + return SafeArea(
  146 + child: Column(
  147 + children: [
  148 + Text(topics?.word ?? '',
  149 + softWrap: true,
  150 + style: TextStyle(
  151 + fontSize: 21.sp, color: const Color(0xFF333333))),
  152 + 26.verticalSpace,
  153 + SizedBox(
  154 + height: 143.h,
  155 + width: 143.w * (topics?.topicAnswerList?.length ?? 0),
  156 + child: ListView.builder(
  157 + scrollDirection: Axis.horizontal,
  158 + physics: const NeverScrollableScrollPhysics(),
  159 + itemCount: topics?.topicAnswerList?.length ?? 0,
  160 + itemBuilder: (context, index) {
  161 + return _decodeImageWidget(
  162 + index, topics?.topicAnswerList?[index]);
  163 + }),
  164 + ),
  165 + ],
155 ), 166 ),
156 - ],  
157 - ),  
158 - );  
159 - }); 167 + );
  168 + });
160 169
161 Widget _decodeImageWidget( 170 Widget _decodeImageWidget(
162 int index, CourseProcessTopicsTopicAnswerList? answerLis) => 171 int index, CourseProcessTopicsTopicAnswerList? answerLis) =>
@@ -198,33 +207,35 @@ class _TopicPicturePage extends StatelessWidget { @@ -198,33 +207,35 @@ class _TopicPicturePage extends StatelessWidget {
198 }); 207 });
199 208
200 ///看题选字 209 ///看题选字
201 - Widget _pageViewWordItemWidget(CourseProcessTopics? topics) => 210 + Widget _pageViewWordItemWidget(
  211 + CourseProcessTopics? topics, bool isCurrentPage) =>
202 BlocBuilder<TopicPictureBloc, TopicPictureState>( 212 BlocBuilder<TopicPictureBloc, TopicPictureState>(
  213 + buildWhen: (_, s) => isCurrentPage,
203 builder: (context, state) { 214 builder: (context, state) {
204 - return SafeArea(  
205 - child: Column(  
206 - children: [  
207 - Text(topics?.word ?? '',  
208 - softWrap: true,  
209 - style: TextStyle(  
210 - fontSize: 21.sp, color: const Color(0xFF333333))),  
211 - 26.verticalSpace,  
212 - SizedBox(  
213 - height: 143.h,  
214 - width: 143.w * (topics?.topicAnswerList?.length ?? 0),  
215 - child: ListView.builder(  
216 - scrollDirection: Axis.horizontal,  
217 - itemCount: topics?.topicAnswerList?.length ?? 0,  
218 - physics: const NeverScrollableScrollPhysics(),  
219 - itemBuilder: (context, index) {  
220 - return _decodeWordWidget(  
221 - index, topics?.topicAnswerList?[index]);  
222 - }), 215 + return SafeArea(
  216 + child: Column(
  217 + children: [
  218 + Text(topics?.word ?? '',
  219 + softWrap: true,
  220 + style: TextStyle(
  221 + fontSize: 21.sp, color: const Color(0xFF333333))),
  222 + 26.verticalSpace,
  223 + SizedBox(
  224 + height: 143.h,
  225 + width: 143.w * (topics?.topicAnswerList?.length ?? 0),
  226 + child: ListView.builder(
  227 + scrollDirection: Axis.horizontal,
  228 + itemCount: topics?.topicAnswerList?.length ?? 0,
  229 + physics: const NeverScrollableScrollPhysics(),
  230 + itemBuilder: (context, index) {
  231 + return _decodeWordWidget(
  232 + index, topics?.topicAnswerList?[index]);
  233 + }),
  234 + ),
  235 + ],
223 ), 236 ),
224 - ],  
225 - ),  
226 - );  
227 - }); 237 + );
  238 + });
228 239
229 Widget _decodeWordWidget( 240 Widget _decodeWordWidget(
230 int index, CourseProcessTopicsTopicAnswerList? answerLis) => 241 int index, CourseProcessTopicsTopicAnswerList? answerLis) =>
@@ -285,9 +296,12 @@ class _TopicPicturePage extends StatelessWidget { @@ -285,9 +296,12 @@ class _TopicPicturePage extends StatelessWidget {
285 }); 296 });
286 297
287 ///听音选图 298 ///听音选图
288 - Widget _pageViewVoicePictureItemWidget(CourseProcessTopics? topics) => 299 + Widget _pageViewVoicePictureItemWidget(
  300 + CourseProcessTopics? topics, bool isCurrentPage) =>
289 BlocBuilder<TopicPictureBloc, TopicPictureState>( 301 BlocBuilder<TopicPictureBloc, TopicPictureState>(
290 - builder: (context, state) { 302 + buildWhen: (previous, current) {
  303 + return isCurrentPage;
  304 + }, builder: (context, state) {
291 final bloc = BlocProvider.of<TopicPictureBloc>(context); 305 final bloc = BlocProvider.of<TopicPictureBloc>(context);
292 return SafeArea( 306 return SafeArea(
293 child: Column( 307 child: Column(
@@ -296,10 +310,9 @@ class _TopicPicturePage extends StatelessWidget { @@ -296,10 +310,9 @@ class _TopicPicturePage extends StatelessWidget {
296 mainAxisAlignment: MainAxisAlignment.center, 310 mainAxisAlignment: MainAxisAlignment.center,
297 children: [ 311 children: [
298 SpeakerWidget( 312 SpeakerWidget(
299 - isPlaying: bloc.voicePlayState == VoicePlayState.playing, 313 + isPlaying: isCurrentPage &&
  314 + bloc.voicePlayState == VoicePlayState.playing,
300 // 控制动画播放 315 // 控制动画播放
301 - isClickable: true,  
302 - // 控制是否可点击  
303 width: 32.w, 316 width: 32.w,
304 height: 32.w, 317 height: 32.w,
305 onTap: () { 318 onTap: () {
@@ -368,41 +381,41 @@ class _TopicPicturePage extends StatelessWidget { @@ -368,41 +381,41 @@ class _TopicPicturePage extends StatelessWidget {
368 }); 381 });
369 382
370 ///听音选字 383 ///听音选字
371 - Widget _pageViewVoiceWordItemWidget(CourseProcessTopics? topics) => 384 + Widget _pageViewVoiceWordItemWidget(
  385 + CourseProcessTopics? topics, bool isCurrentPage) =>
372 BlocBuilder<TopicPictureBloc, TopicPictureState>( 386 BlocBuilder<TopicPictureBloc, TopicPictureState>(
  387 + buildWhen: (_, s) => isCurrentPage,
373 builder: (context, state) { 388 builder: (context, state) {
374 - final bloc = BlocProvider.of<TopicPictureBloc>(context);  
375 - return SafeArea(  
376 - child: Column(  
377 - children: [  
378 - SpeakerWidget(  
379 - isPlaying: bloc.voicePlayState == VoicePlayState.playing,  
380 - // 控制动画播放  
381 - isClickable: true,  
382 - // 控制是否可点击  
383 - width: 32.w,  
384 - height: 32.w,  
385 - onTap: () {  
386 - bloc.add(VoicePlayEvent());  
387 - },  
388 - ),  
389 - 26.verticalSpace,  
390 - SizedBox(  
391 - width: 163.w * (topics?.topicAnswerList?.length ?? 0),  
392 - height: 143.h,  
393 - child: ListView.builder(  
394 - scrollDirection: Axis.horizontal,  
395 - itemCount: topics?.topicAnswerList?.length,  
396 - physics: const NeverScrollableScrollPhysics(),  
397 - itemBuilder: (BuildContext context, int index) {  
398 - return _decodeVoiceWordImageWidget(  
399 - index, topics!.topicAnswerList![index]);  
400 - }), 389 + final bloc = BlocProvider.of<TopicPictureBloc>(context);
  390 + return SafeArea(
  391 + child: Column(
  392 + children: [
  393 + SpeakerWidget(
  394 + isPlaying: isCurrentPage &&
  395 + bloc.voicePlayState == VoicePlayState.playing,
  396 + width: 32.w,
  397 + height: 32.w,
  398 + onTap: () {
  399 + bloc.add(VoicePlayEvent());
  400 + },
  401 + ),
  402 + 26.verticalSpace,
  403 + SizedBox(
  404 + width: 163.w * (topics?.topicAnswerList?.length ?? 0),
  405 + height: 143.h,
  406 + child: ListView.builder(
  407 + scrollDirection: Axis.horizontal,
  408 + itemCount: topics?.topicAnswerList?.length,
  409 + physics: const NeverScrollableScrollPhysics(),
  410 + itemBuilder: (BuildContext context, int index) {
  411 + return _decodeVoiceWordImageWidget(
  412 + index, topics!.topicAnswerList![index]);
  413 + }),
  414 + ),
  415 + ],
401 ), 416 ),
402 - ],  
403 - ),  
404 - );  
405 - }); 417 + );
  418 + });
406 419
407 Widget _decodeVoiceWordImageWidget( 420 Widget _decodeVoiceWordImageWidget(
408 int index, CourseProcessTopicsTopicAnswerList answerList) => 421 int index, CourseProcessTopicsTopicAnswerList answerList) =>
@@ -465,71 +478,74 @@ class _TopicPicturePage extends StatelessWidget { @@ -465,71 +478,74 @@ class _TopicPicturePage extends StatelessWidget {
465 }); 478 });
466 479
467 ///语音问答 480 ///语音问答
468 - Widget _voiceAnswerItem(CourseProcessTopics? topics) => 481 + Widget _voiceAnswerItem(CourseProcessTopics? topics, bool isCurrentPage) =>
469 BlocBuilder<TopicPictureBloc, TopicPictureState>( 482 BlocBuilder<TopicPictureBloc, TopicPictureState>(
  483 + buildWhen: (_, s) => isCurrentPage,
470 builder: (context, state) { 484 builder: (context, state) {
471 - final bloc = BlocProvider.of<TopicPictureBloc>(context);  
472 - return Row(  
473 - mainAxisAlignment: MainAxisAlignment.center,  
474 - children: [  
475 - ClipRRect(  
476 - borderRadius: BorderRadius.circular(20),  
477 - child: Container(  
478 - color: Colors.white,  
479 - child: OwImageWidget(  
480 - name: topics?.picUrl ?? '',  
481 - height: 186.h,  
482 - width: 186.w,  
483 - ),  
484 - ),  
485 - ),  
486 - 120.horizontalSpace,  
487 - Column( 485 + final bloc = BlocProvider.of<TopicPictureBloc>(context);
  486 + return Row(
488 mainAxisAlignment: MainAxisAlignment.center, 487 mainAxisAlignment: MainAxisAlignment.center,
489 children: [ 488 children: [
490 - Row( 489 + ClipRRect(
  490 + borderRadius: BorderRadius.circular(20),
  491 + child: Container(
  492 + color: Colors.white,
  493 + child: OwImageWidget(
  494 + name: topics?.picUrl ?? '',
  495 + height: 186.h,
  496 + width: 186.w,
  497 + ),
  498 + ),
  499 + ),
  500 + 120.horizontalSpace,
  501 + Column(
  502 + mainAxisAlignment: MainAxisAlignment.center,
491 children: [ 503 children: [
492 - SpeakerWidget(  
493 - isPlaying: bloc.voicePlayState == VoicePlayState.playing,  
494 - // 控制动画播放  
495 - isClickable: !bloc.isRecording,  
496 - // 控制是否可点击  
497 - width: 45.w,  
498 - height: 45.w, 504 + Row(
  505 + children: [
  506 + SpeakerWidget(
  507 + isPlaying: isCurrentPage &&
  508 + bloc.voicePlayState == VoicePlayState.playing,
  509 + // 控制动画播放
  510 + isClickable: !bloc.isRecording,
  511 + // 控制是否可点击
  512 + width: 45.w,
  513 + height: 45.w,
  514 + onTap: () {
  515 + bloc.add(VoicePlayEvent());
  516 + },
  517 + ),
  518 + 10.horizontalSpace,
  519 + Text(topics?.word ?? '')
  520 + ],
  521 + ),
  522 + 70.verticalSpace,
  523 + RecorderWidget(
  524 + isPlaying: bloc.isRecording,
  525 + isClickable:
  526 + bloc.voicePlayState != VoicePlayState.playing,
  527 + width: 72.w,
  528 + height: 72.w,
499 onTap: () { 529 onTap: () {
500 - bloc.add(VoicePlayEvent()); 530 + if (bloc.isRecording) {
  531 + bloc.add(XSVoiceStopEvent());
  532 + return;
  533 + }
  534 + if (topics?.type == TopicType.voiceQuestion.value ||
  535 + topics?.type == TopicType.voiceWord.value) {
  536 + bloc.add(XSVoiceStartEvent(topics?.keyWord ?? '', '0',
  537 + UserUtil.getUser()!.id.toString()));
  538 + } else {
  539 + bloc.add(XSVoiceStartEvent(topics?.word ?? '', '0',
  540 + UserUtil.getUser()!.id.toString()));
  541 + }
501 }, 542 },
502 ), 543 ),
503 - 10.horizontalSpace,  
504 - Text(topics?.word ?? '')  
505 ], 544 ],
506 - ),  
507 - 70.verticalSpace,  
508 - RecorderWidget(  
509 - isPlaying: bloc.isRecording,  
510 - isClickable: bloc.voicePlayState != VoicePlayState.playing,  
511 - width: 72.w,  
512 - height: 72.w,  
513 - onTap: () {  
514 - if (bloc.isRecording) {  
515 - bloc.add(XSVoiceStopEvent());  
516 - return;  
517 - }  
518 - if (topics?.type == TopicType.voiceQuestion.value ||  
519 - topics?.type == TopicType.voiceWord.value) {  
520 - bloc.add(XSVoiceStartEvent(topics?.keyWord ?? '', '0',  
521 - UserUtil.getUser()!.id.toString()));  
522 - } else {  
523 - bloc.add(XSVoiceStartEvent(topics?.word ?? '', '0',  
524 - UserUtil.getUser()!.id.toString()));  
525 - }  
526 - },  
527 - ), 545 + )
528 ], 546 ],
529 - )  
530 - ],  
531 - );  
532 - }); 547 + );
  548 + });
533 549
534 Color getResultColor(bool correct) { 550 Color getResultColor(bool correct) {
535 if (correct) { 551 if (correct) {