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 93 bloc.add(CurrentPageIndexChangeEvent(index));
94 94 },
95 95 itemBuilder: (BuildContext context, int index) {
  96 + final bloc =
  97 + BlocProvider.of<TopicPictureBloc>(context);
96 98 CourseProcessTopics? topics =
97 99 bloc.entity?.topics![index];
  100 + bool isCurrentPage =
  101 + index == bloc.currentPage - 1;
98 102 if (topics?.type ==
99 103 TopicType.audioImageSelect.value) {
100 104 //听音选图
101 105 return _pageViewVoicePictureItemWidget(
102   - topics);
  106 + topics, isCurrentPage);
103 107 } else if (topics?.type ==
104 108 TopicType.audioCharSelect.value) {
105 109 //听音选字
106   - return _pageViewVoiceWordItemWidget(topics);
  110 + return _pageViewVoiceWordItemWidget(
  111 + topics, isCurrentPage);
107 112 } else if (topics?.type ==
108 113 TopicType.questionCharSelect.value) {
109 114 //看题选字
110   - return _pageViewWordItemWidget(topics);
  115 + return _pageViewWordItemWidget(
  116 + topics, isCurrentPage);
111 117 } else if (topics?.type ==
112 118 TopicType.questionImageSelect.value) {
113 119 //看题选图
114   - return _pageViewItemWidget(topics);
  120 + return _pageViewItemWidget(
  121 + topics, isCurrentPage);
115 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 138 });
131 139  
132 140 ///看题选图
133   - Widget _pageViewItemWidget(CourseProcessTopics? topics) =>
  141 + Widget _pageViewItemWidget(CourseProcessTopics? topics, bool isCurrentPage) =>
134 142 BlocBuilder<TopicPictureBloc, TopicPictureState>(
  143 + buildWhen: (_, s) => isCurrentPage,
135 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 170 Widget _decodeImageWidget(
162 171 int index, CourseProcessTopicsTopicAnswerList? answerLis) =>
... ... @@ -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 212 BlocBuilder<TopicPictureBloc, TopicPictureState>(
  213 + buildWhen: (_, s) => isCurrentPage,
203 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 240 Widget _decodeWordWidget(
230 241 int index, CourseProcessTopicsTopicAnswerList? answerLis) =>
... ... @@ -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 301 BlocBuilder<TopicPictureBloc, TopicPictureState>(
290   - builder: (context, state) {
  302 + buildWhen: (previous, current) {
  303 + return isCurrentPage;
  304 + }, builder: (context, state) {
291 305 final bloc = BlocProvider.of<TopicPictureBloc>(context);
292 306 return SafeArea(
293 307 child: Column(
... ... @@ -296,10 +310,9 @@ class _TopicPicturePage extends StatelessWidget {
296 310 mainAxisAlignment: MainAxisAlignment.center,
297 311 children: [
298 312 SpeakerWidget(
299   - isPlaying: bloc.voicePlayState == VoicePlayState.playing,
  313 + isPlaying: isCurrentPage &&
  314 + bloc.voicePlayState == VoicePlayState.playing,
300 315 // 控制动画播放
301   - isClickable: true,
302   - // 控制是否可点击
303 316 width: 32.w,
304 317 height: 32.w,
305 318 onTap: () {
... ... @@ -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 386 BlocBuilder<TopicPictureBloc, TopicPictureState>(
  387 + buildWhen: (_, s) => isCurrentPage,
373 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 420 Widget _decodeVoiceWordImageWidget(
408 421 int index, CourseProcessTopicsTopicAnswerList answerList) =>
... ... @@ -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 482 BlocBuilder<TopicPictureBloc, TopicPictureState>(
  483 + buildWhen: (_, s) => isCurrentPage,
470 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 487 mainAxisAlignment: MainAxisAlignment.center,
489 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 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 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 550 Color getResultColor(bool correct) {
535 551 if (correct) {
... ...