Commit 2512b58cfb93b0db16705ff0f2cc99cb6e84b76e
1 parent
0ebc6186
feat:性能优化-练习页PageView根据是否是当前页来决定build以及SpeakerWidget组件isPlaying
Showing
1 changed file
with
161 additions
and
145 deletions
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) { | ... | ... |