Commit fd737d6ae275311fe88db3416e3dd53cbd382d9d
1 parent
d0623cfd
feat:绘本作答结果以单词为单位根据分数展示不同颜色
Showing
7 changed files
with
261 additions
and
9 deletions
lib/generated/json/base/json_convert_content.dart
@@ -16,6 +16,7 @@ import 'package:wow_english/models/follow_read_entity.dart'; | @@ -16,6 +16,7 @@ import 'package:wow_english/models/follow_read_entity.dart'; | ||
16 | import 'package:wow_english/models/listen_entity.dart'; | 16 | import 'package:wow_english/models/listen_entity.dart'; |
17 | import 'package:wow_english/models/product_entity.dart'; | 17 | import 'package:wow_english/models/product_entity.dart'; |
18 | import 'package:wow_english/models/read_content_entity.dart'; | 18 | import 'package:wow_english/models/read_content_entity.dart'; |
19 | +import 'package:wow_english/models/singsound_result_detail_entity.dart'; | ||
19 | import 'package:wow_english/models/user_entity.dart'; | 20 | import 'package:wow_english/models/user_entity.dart'; |
20 | 21 | ||
21 | JsonConvert jsonConvert = JsonConvert(); | 22 | JsonConvert jsonConvert = JsonConvert(); |
@@ -232,6 +233,10 @@ class JsonConvert { | @@ -232,6 +233,10 @@ class JsonConvert { | ||
232 | return data.map<ReadContentEntity>((Map<String, dynamic> e) => | 233 | return data.map<ReadContentEntity>((Map<String, dynamic> e) => |
233 | ReadContentEntity.fromJson(e)).toList() as M; | 234 | ReadContentEntity.fromJson(e)).toList() as M; |
234 | } | 235 | } |
236 | + if (<SingsoundResultDetailEntity>[] is M) { | ||
237 | + return data.map<SingsoundResultDetailEntity>((Map<String, dynamic> e) => | ||
238 | + SingsoundResultDetailEntity.fromJson(e)).toList() as M; | ||
239 | + } | ||
235 | if (<UserEntity>[] is M) { | 240 | if (<UserEntity>[] is M) { |
236 | return data.map<UserEntity>((Map<String, dynamic> e) => | 241 | return data.map<UserEntity>((Map<String, dynamic> e) => |
237 | UserEntity.fromJson(e)).toList() as M; | 242 | UserEntity.fromJson(e)).toList() as M; |
@@ -278,6 +283,8 @@ class JsonConvertClassCollection { | @@ -278,6 +283,8 @@ class JsonConvertClassCollection { | ||
278 | (ListenEntity).toString(): ListenEntity.fromJson, | 283 | (ListenEntity).toString(): ListenEntity.fromJson, |
279 | (ProductEntity).toString(): ProductEntity.fromJson, | 284 | (ProductEntity).toString(): ProductEntity.fromJson, |
280 | (ReadContentEntity).toString(): ReadContentEntity.fromJson, | 285 | (ReadContentEntity).toString(): ReadContentEntity.fromJson, |
286 | + (SingsoundResultDetailEntity).toString(): SingsoundResultDetailEntity | ||
287 | + .fromJson, | ||
281 | (UserEntity).toString(): UserEntity.fromJson, | 288 | (UserEntity).toString(): UserEntity.fromJson, |
282 | }; | 289 | }; |
283 | 290 |
lib/generated/json/course_process_entity.g.dart
1 | import 'package:wow_english/generated/json/base/json_convert_content.dart'; | 1 | import 'package:wow_english/generated/json/base/json_convert_content.dart'; |
2 | import 'package:wow_english/models/course_process_entity.dart'; | 2 | import 'package:wow_english/models/course_process_entity.dart'; |
3 | +import 'package:wow_english/models/singsound_result_detail_entity.dart'; | ||
4 | + | ||
3 | 5 | ||
4 | CourseProcessEntity $CourseProcessEntityFromJson(Map<String, dynamic> json) { | 6 | CourseProcessEntity $CourseProcessEntityFromJson(Map<String, dynamic> json) { |
5 | final CourseProcessEntity courseProcessEntity = CourseProcessEntity(); | 7 | final CourseProcessEntity courseProcessEntity = CourseProcessEntity(); |
@@ -114,6 +116,15 @@ CourseProcessReadings $CourseProcessReadingsFromJson( | @@ -114,6 +116,15 @@ CourseProcessReadings $CourseProcessReadingsFromJson( | ||
114 | if (recordScore != null) { | 116 | if (recordScore != null) { |
115 | courseProcessReadings.recordScore = recordScore; | 117 | courseProcessReadings.recordScore = recordScore; |
116 | } | 118 | } |
119 | + final List< | ||
120 | + SingsoundResultDetailEntity>? resultDetails = (json['resultDetails'] as List< | ||
121 | + dynamic>?)?.map( | ||
122 | + (e) => | ||
123 | + jsonConvert.convert<SingsoundResultDetailEntity>( | ||
124 | + e) as SingsoundResultDetailEntity).toList(); | ||
125 | + if (resultDetails != null) { | ||
126 | + courseProcessReadings.resultDetails = resultDetails; | ||
127 | + } | ||
117 | return courseProcessReadings; | 128 | return courseProcessReadings; |
118 | } | 129 | } |
119 | 130 | ||
@@ -132,6 +143,7 @@ Map<String, dynamic> $CourseProcessReadingsToJson( | @@ -132,6 +143,7 @@ Map<String, dynamic> $CourseProcessReadingsToJson( | ||
132 | data['word'] = entity.word; | 143 | data['word'] = entity.word; |
133 | data['recordUrl'] = entity.recordUrl; | 144 | data['recordUrl'] = entity.recordUrl; |
134 | data['recordScore'] = entity.recordScore; | 145 | data['recordScore'] = entity.recordScore; |
146 | + data['resultDetails'] = entity.resultDetails?.map((v) => v.toJson()).toList(); | ||
135 | return data; | 147 | return data; |
136 | } | 148 | } |
137 | 149 | ||
@@ -149,6 +161,7 @@ extension CourseProcessReadingsExtension on CourseProcessReadings { | @@ -149,6 +161,7 @@ extension CourseProcessReadingsExtension on CourseProcessReadings { | ||
149 | String? word, | 161 | String? word, |
150 | String? recordUrl, | 162 | String? recordUrl, |
151 | String? recordScore, | 163 | String? recordScore, |
164 | + List<SingsoundResultDetailEntity>? resultDetails, | ||
152 | }) { | 165 | }) { |
153 | return CourseProcessReadings() | 166 | return CourseProcessReadings() |
154 | ..audioUrl = audioUrl ?? this.audioUrl | 167 | ..audioUrl = audioUrl ?? this.audioUrl |
@@ -162,7 +175,8 @@ extension CourseProcessReadingsExtension on CourseProcessReadings { | @@ -162,7 +175,8 @@ extension CourseProcessReadingsExtension on CourseProcessReadings { | ||
162 | ..sortOrder = sortOrder ?? this.sortOrder | 175 | ..sortOrder = sortOrder ?? this.sortOrder |
163 | ..word = word ?? this.word | 176 | ..word = word ?? this.word |
164 | ..recordUrl = recordUrl ?? this.recordUrl | 177 | ..recordUrl = recordUrl ?? this.recordUrl |
165 | - ..recordScore = recordScore ?? this.recordScore; | 178 | + ..recordScore = recordScore ?? this.recordScore |
179 | + ..resultDetails = resultDetails ?? this.resultDetails; | ||
166 | } | 180 | } |
167 | } | 181 | } |
168 | 182 |
lib/generated/json/singsound_result_detail_entity.g.dart
0 → 100644
1 | +import 'package:wow_english/generated/json/base/json_convert_content.dart'; | ||
2 | +import 'package:wow_english/models/singsound_result_detail_entity.dart'; | ||
3 | + | ||
4 | +SingsoundResultDetailEntity $SingsoundResultDetailEntityFromJson( | ||
5 | + Map<String, dynamic> json) { | ||
6 | + final SingsoundResultDetailEntity singsoundResultDetailEntity = SingsoundResultDetailEntity(); | ||
7 | + final int? dpType = jsonConvert.convert<int>(json['dp_type']); | ||
8 | + if (dpType != null) { | ||
9 | + singsoundResultDetailEntity.dpType = dpType; | ||
10 | + } | ||
11 | + final int? tonescore = jsonConvert.convert<int>(json['tonescore']); | ||
12 | + if (tonescore != null) { | ||
13 | + singsoundResultDetailEntity.tonescore = tonescore; | ||
14 | + } | ||
15 | + final int? dur = jsonConvert.convert<int>(json['dur']); | ||
16 | + if (dur != null) { | ||
17 | + singsoundResultDetailEntity.dur = dur; | ||
18 | + } | ||
19 | + final int? liaisonref = jsonConvert.convert<int>(json['liaisonref']); | ||
20 | + if (liaisonref != null) { | ||
21 | + singsoundResultDetailEntity.liaisonref = liaisonref; | ||
22 | + } | ||
23 | + final int? stressref = jsonConvert.convert<int>(json['stressref']); | ||
24 | + if (stressref != null) { | ||
25 | + singsoundResultDetailEntity.stressref = stressref; | ||
26 | + } | ||
27 | + final int? senseref = jsonConvert.convert<int>(json['senseref']); | ||
28 | + if (senseref != null) { | ||
29 | + singsoundResultDetailEntity.senseref = senseref; | ||
30 | + } | ||
31 | + final int? start = jsonConvert.convert<int>(json['start']); | ||
32 | + if (start != null) { | ||
33 | + singsoundResultDetailEntity.start = start; | ||
34 | + } | ||
35 | + final int? liaisonscore = jsonConvert.convert<int>(json['liaisonscore']); | ||
36 | + if (liaisonscore != null) { | ||
37 | + singsoundResultDetailEntity.liaisonscore = liaisonscore; | ||
38 | + } | ||
39 | + final int? fluency = jsonConvert.convert<int>(json['fluency']); | ||
40 | + if (fluency != null) { | ||
41 | + singsoundResultDetailEntity.fluency = fluency; | ||
42 | + } | ||
43 | + final String? char = jsonConvert.convert<String>(json['char']); | ||
44 | + if (char != null) { | ||
45 | + singsoundResultDetailEntity.char = char; | ||
46 | + } | ||
47 | + final int? toneref = jsonConvert.convert<int>(json['toneref']); | ||
48 | + if (toneref != null) { | ||
49 | + singsoundResultDetailEntity.toneref = toneref; | ||
50 | + } | ||
51 | + final int? stressscore = jsonConvert.convert<int>(json['stressscore']); | ||
52 | + if (stressscore != null) { | ||
53 | + singsoundResultDetailEntity.stressscore = stressscore; | ||
54 | + } | ||
55 | + final int? score = jsonConvert.convert<int>(json['score']); | ||
56 | + if (score != null) { | ||
57 | + singsoundResultDetailEntity.score = score; | ||
58 | + } | ||
59 | + final int? end = jsonConvert.convert<int>(json['end']); | ||
60 | + if (end != null) { | ||
61 | + singsoundResultDetailEntity.end = end; | ||
62 | + } | ||
63 | + final int? sensescore = jsonConvert.convert<int>(json['sensescore']); | ||
64 | + if (sensescore != null) { | ||
65 | + singsoundResultDetailEntity.sensescore = sensescore; | ||
66 | + } | ||
67 | + return singsoundResultDetailEntity; | ||
68 | +} | ||
69 | + | ||
70 | +Map<String, dynamic> $SingsoundResultDetailEntityToJson( | ||
71 | + SingsoundResultDetailEntity entity) { | ||
72 | + final Map<String, dynamic> data = <String, dynamic>{}; | ||
73 | + data['dp_type'] = entity.dpType; | ||
74 | + data['tonescore'] = entity.tonescore; | ||
75 | + data['dur'] = entity.dur; | ||
76 | + data['liaisonref'] = entity.liaisonref; | ||
77 | + data['stressref'] = entity.stressref; | ||
78 | + data['senseref'] = entity.senseref; | ||
79 | + data['start'] = entity.start; | ||
80 | + data['liaisonscore'] = entity.liaisonscore; | ||
81 | + data['fluency'] = entity.fluency; | ||
82 | + data['char'] = entity.char; | ||
83 | + data['toneref'] = entity.toneref; | ||
84 | + data['stressscore'] = entity.stressscore; | ||
85 | + data['score'] = entity.score; | ||
86 | + data['end'] = entity.end; | ||
87 | + data['sensescore'] = entity.sensescore; | ||
88 | + return data; | ||
89 | +} | ||
90 | + | ||
91 | +extension SingsoundResultDetailEntityExtension on SingsoundResultDetailEntity { | ||
92 | + SingsoundResultDetailEntity copyWith({ | ||
93 | + int? dpType, | ||
94 | + int? tonescore, | ||
95 | + int? dur, | ||
96 | + int? liaisonref, | ||
97 | + int? stressref, | ||
98 | + int? senseref, | ||
99 | + int? start, | ||
100 | + int? liaisonscore, | ||
101 | + int? fluency, | ||
102 | + String? char, | ||
103 | + int? toneref, | ||
104 | + int? stressscore, | ||
105 | + int? score, | ||
106 | + int? end, | ||
107 | + int? sensescore, | ||
108 | + }) { | ||
109 | + return SingsoundResultDetailEntity() | ||
110 | + ..dpType = dpType ?? this.dpType | ||
111 | + ..tonescore = tonescore ?? this.tonescore | ||
112 | + ..dur = dur ?? this.dur | ||
113 | + ..liaisonref = liaisonref ?? this.liaisonref | ||
114 | + ..stressref = stressref ?? this.stressref | ||
115 | + ..senseref = senseref ?? this.senseref | ||
116 | + ..start = start ?? this.start | ||
117 | + ..liaisonscore = liaisonscore ?? this.liaisonscore | ||
118 | + ..fluency = fluency ?? this.fluency | ||
119 | + ..char = char ?? this.char | ||
120 | + ..toneref = toneref ?? this.toneref | ||
121 | + ..stressscore = stressscore ?? this.stressscore | ||
122 | + ..score = score ?? this.score | ||
123 | + ..end = end ?? this.end | ||
124 | + ..sensescore = sensescore ?? this.sensescore; | ||
125 | + } | ||
126 | +} | ||
0 | \ No newline at end of file | 127 | \ No newline at end of file |
lib/models/course_process_entity.dart
@@ -2,6 +2,8 @@ import 'package:wow_english/generated/json/base/json_field.dart'; | @@ -2,6 +2,8 @@ import 'package:wow_english/generated/json/base/json_field.dart'; | ||
2 | import 'package:wow_english/generated/json/course_process_entity.g.dart'; | 2 | import 'package:wow_english/generated/json/course_process_entity.g.dart'; |
3 | import 'dart:convert'; | 3 | import 'dart:convert'; |
4 | 4 | ||
5 | +import 'package:wow_english/models/singsound_result_detail_entity.dart'; | ||
6 | + | ||
5 | @JsonSerializable() | 7 | @JsonSerializable() |
6 | class CourseProcessEntity { | 8 | class CourseProcessEntity { |
7 | int? currentStep; | 9 | int? currentStep; |
@@ -36,6 +38,7 @@ class CourseProcessReadings { | @@ -36,6 +38,7 @@ class CourseProcessReadings { | ||
36 | String? word; | 38 | String? word; |
37 | String? recordUrl; | 39 | String? recordUrl; |
38 | String? recordScore; | 40 | String? recordScore; |
41 | + List<SingsoundResultDetailEntity>? resultDetails; | ||
39 | 42 | ||
40 | CourseProcessReadings(); | 43 | CourseProcessReadings(); |
41 | 44 |
lib/models/singsound_result_detail_entity.dart
0 → 100644
1 | +import 'package:wow_english/generated/json/base/json_field.dart'; | ||
2 | +import 'package:wow_english/generated/json/singsound_result_detail_entity.g.dart'; | ||
3 | +import 'dart:convert'; | ||
4 | +export 'package:wow_english/generated/json/singsound_result_detail_entity.g.dart'; | ||
5 | + | ||
6 | +@JsonSerializable() | ||
7 | +class SingsoundResultDetailEntity { | ||
8 | + @JSONField(name: "dp_type") | ||
9 | + late int? dpType; | ||
10 | + late int? tonescore; | ||
11 | + late int? dur; | ||
12 | + late int? liaisonref; | ||
13 | + late int? stressref; | ||
14 | + late int? senseref; | ||
15 | + late int? start; | ||
16 | + late int? liaisonscore; | ||
17 | + late int? fluency; | ||
18 | + late String char; | ||
19 | + late int? toneref; | ||
20 | + late int? stressscore; | ||
21 | + late int score; | ||
22 | + late int? end; | ||
23 | + late int? sensescore; | ||
24 | + | ||
25 | + SingsoundResultDetailEntity(); | ||
26 | + | ||
27 | + // 只接受两个参数的构造函数 | ||
28 | + SingsoundResultDetailEntity.withCharAndScore(this.char, this.score) { | ||
29 | + dpType = null; | ||
30 | + tonescore = null; | ||
31 | + dur = null; | ||
32 | + liaisonref = null; | ||
33 | + stressref = null; | ||
34 | + senseref = null; | ||
35 | + start = null; | ||
36 | + liaisonscore = null; | ||
37 | + fluency = null; | ||
38 | + toneref = null; | ||
39 | + stressscore = null; | ||
40 | + end = null; | ||
41 | + sensescore = null; | ||
42 | + } | ||
43 | + | ||
44 | + factory SingsoundResultDetailEntity.fromJson(Map<String, dynamic> json) => $SingsoundResultDetailEntityFromJson(json); | ||
45 | + | ||
46 | + Map<String, dynamic> toJson() => $SingsoundResultDetailEntityToJson(this); | ||
47 | + | ||
48 | + @override | ||
49 | + String toString() { | ||
50 | + return jsonEncode(this); | ||
51 | + } | ||
52 | +} | ||
0 | \ No newline at end of file | 53 | \ No newline at end of file |
lib/pages/reading/bloc/reading_bloc.dart
@@ -4,6 +4,7 @@ import 'package:flutter/foundation.dart'; | @@ -4,6 +4,7 @@ import 'package:flutter/foundation.dart'; | ||
4 | import 'package:flutter/services.dart'; | 4 | import 'package:flutter/services.dart'; |
5 | import 'package:flutter_bloc/flutter_bloc.dart'; | 5 | import 'package:flutter_bloc/flutter_bloc.dart'; |
6 | import 'package:flutter_easyloading/flutter_easyloading.dart'; | 6 | import 'package:flutter_easyloading/flutter_easyloading.dart'; |
7 | +import 'package:flutter_screenutil/flutter_screenutil.dart'; | ||
7 | import 'package:permission_handler/permission_handler.dart'; | 8 | import 'package:permission_handler/permission_handler.dart'; |
8 | import 'package:wow_english/common/extension/string_extension.dart'; | 9 | import 'package:wow_english/common/extension/string_extension.dart'; |
9 | import 'package:wow_english/pages/reading/widgets/ReadingModeType.dart'; | 10 | import 'package:wow_english/pages/reading/widgets/ReadingModeType.dart'; |
@@ -18,6 +19,7 @@ import '../../../common/request/exception.dart'; | @@ -18,6 +19,7 @@ import '../../../common/request/exception.dart'; | ||
18 | import '../../../common/utils/click_with_music_controller.dart'; | 19 | import '../../../common/utils/click_with_music_controller.dart'; |
19 | import '../../../common/utils/show_star_reward_dialog.dart'; | 20 | import '../../../common/utils/show_star_reward_dialog.dart'; |
20 | import '../../../models/course_process_entity.dart'; | 21 | import '../../../models/course_process_entity.dart'; |
22 | +import '../../../models/singsound_result_detail_entity.dart'; | ||
21 | import '../../../models/voice_result_type.dart'; | 23 | import '../../../models/voice_result_type.dart'; |
22 | import '../../../route/route.dart'; | 24 | import '../../../route/route.dart'; |
23 | import '../../../utils/loading.dart'; | 25 | import '../../../utils/loading.dart'; |
@@ -308,6 +310,41 @@ class ReadingPageBloc | @@ -308,6 +310,41 @@ class ReadingPageBloc | ||
308 | return currentPageData()?.word?.trim() ?? ''; | 310 | return currentPageData()?.word?.trim() ?? ''; |
309 | } | 311 | } |
310 | 312 | ||
313 | + /// 结合单词分数返回带颜色的TextSpan数组 | ||
314 | + List<TextSpan>? displayContent() { | ||
315 | + // return _textController.text.isNotEmpty ? _textController.text : readingContent(); | ||
316 | + // 创建用于展示每个单词的 TextSpan 列表 | ||
317 | + if (currentPageData() == null) { | ||
318 | + return null; | ||
319 | + } | ||
320 | + List<SingsoundResultDetailEntity> resultDetails; | ||
321 | + if (currentPageData()?.resultDetails != null) { | ||
322 | + resultDetails = currentPageData()!.resultDetails!; | ||
323 | + } else { | ||
324 | + List<String>? wordList = currentPageData()?.word?.split(RegExp(r'\s+')); | ||
325 | + resultDetails = wordList! | ||
326 | + .map( | ||
327 | + (word) => SingsoundResultDetailEntity.withCharAndScore(word, 0)) | ||
328 | + .toList(); | ||
329 | + } | ||
330 | + List<TextSpan> textSpans = resultDetails.asMap().entries.map((entry) { | ||
331 | + int index = entry.key; | ||
332 | + SingsoundResultDetailEntity detail = entry.value; | ||
333 | + // Check if this is the last word in the list | ||
334 | + bool isLastWord = index == resultDetails.length - 1; | ||
335 | + return TextSpan( | ||
336 | + text: '${detail.char}${isLastWord ? '' : ' '}', | ||
337 | + style: TextStyle( | ||
338 | + color: detail.score > 80 | ||
339 | + ? const Color(0XFF35C137) | ||
340 | + : const Color(0xFF333333), | ||
341 | + fontSize: 20.sp, | ||
342 | + ), | ||
343 | + ); | ||
344 | + }).toList(); | ||
345 | + return textSpans; | ||
346 | + } | ||
347 | + | ||
311 | void nextPage() { | 348 | void nextPage() { |
312 | if (currentPage >= dataCount()) { | 349 | if (currentPage >= dataCount()) { |
313 | sectionComplete(() { | 350 | sectionComplete(() { |
@@ -362,12 +399,23 @@ class ReadingPageBloc | @@ -362,12 +399,23 @@ class ReadingPageBloc | ||
362 | final result = args['result'] as Map; | 399 | final result = args['result'] as Map; |
363 | Log.d("_voiceXsResult result=$result"); | 400 | Log.d("_voiceXsResult result=$result"); |
364 | final overall = result['overall'].toString(); | 401 | final overall = result['overall'].toString(); |
402 | + List<dynamic> resultDetailsJsons = result['details']; | ||
403 | + // 提取 score 和 char 字段 | ||
404 | + List<SingsoundResultDetailEntity> detailEntities = []; | ||
405 | + for (var detail in resultDetailsJsons) { | ||
406 | + int score = detail['score'] as int; | ||
407 | + String char = detail['char'] as String; | ||
408 | + detailEntities | ||
409 | + .add(SingsoundResultDetailEntity.withCharAndScore(char, score)); | ||
410 | + } | ||
365 | 411 | ||
366 | ///todo 后面可以考虑要不要传自己的服务器 | 412 | ///todo 后面可以考虑要不要传自己的服务器 |
367 | final recordFileUrl = args['audioUrl'].toString(); | 413 | final recordFileUrl = args['audioUrl'].toString(); |
368 | int score = int.parse(overall); | 414 | int score = int.parse(overall); |
369 | currentPageData()?.recordScore = overall; | 415 | currentPageData()?.recordScore = overall; |
370 | currentPageData()?.recordUrl = recordFileUrl.assetMp3; | 416 | currentPageData()?.recordUrl = recordFileUrl.assetMp3; |
417 | + currentPageData()?.resultDetails = detailEntities; | ||
418 | + add(OnXSVoiceStateChangeEvent()); | ||
371 | 419 | ||
372 | final voiceResult = VoiceResultType.fromScore(score); | 420 | final voiceResult = VoiceResultType.fromScore(score); |
373 | if (voiceResult.lottieFilePath != null) { | 421 | if (voiceResult.lottieFilePath != null) { |
lib/pages/reading/reading_page.dart
@@ -154,7 +154,7 @@ class _ReadingPage extends StatelessWidget { | @@ -154,7 +154,7 @@ class _ReadingPage extends StatelessWidget { | ||
154 | Align( | 154 | Align( |
155 | alignment: Alignment.bottomLeft, | 155 | alignment: Alignment.bottomLeft, |
156 | child: Container( | 156 | child: Container( |
157 | - color: const Color(0x80FFFFFF), | 157 | + color: const Color(0xCCFFFFFF), |
158 | child: Row( | 158 | child: Row( |
159 | children: [ | 159 | children: [ |
160 | 5.horizontalSpace, | 160 | 5.horizontalSpace, |
@@ -175,13 +175,15 @@ class _ReadingPage extends StatelessWidget { | @@ -175,13 +175,15 @@ class _ReadingPage extends StatelessWidget { | ||
175 | width: 10.w, | 175 | width: 10.w, |
176 | ), | 176 | ), |
177 | Expanded( | 177 | Expanded( |
178 | - child: Text( | ||
179 | - bloc.readingContent(), | ||
180 | - style: TextStyle( | ||
181 | - color: const Color(0xFF333333), fontSize: 21.sp), | ||
182 | - maxLines: 2, | ||
183 | - overflow: TextOverflow.ellipsis, | ||
184 | - )), | 178 | + child: RichText( |
179 | + text: TextSpan( | ||
180 | + style: DefaultTextStyle.of(context).style, | ||
181 | + children: bloc.displayContent(), | ||
182 | + ), | ||
183 | + maxLines: 2, | ||
184 | + overflow: TextOverflow.ellipsis, | ||
185 | + ), | ||
186 | + ), | ||
185 | SizedBox( | 187 | SizedBox( |
186 | width: 10.w, | 188 | width: 10.w, |
187 | ), | 189 | ), |