【发布时间】:2020-09-26 11:16:22
【问题描述】:
一个设计模式类型的问题。我正在使用 Flutter 的 TextToSpeech 包。
用户按下播放 (UI) 这会将播放事件传递给 Bloc,该 bloc 创建一个 TTSPlayer 对象并将字符串列表 (TTSScript) 传递给它。 TTS 通过迭代读出列表中的每个字符串。
问题: 我希望每次 TTSPlayer 移动到列表中的下一个字符串时,该集团都调度一个事件,以便我可以在屏幕上显示当前字符串。
但是: 如何将 'currentTextUpdatedEvent' 从 TTSPlayer 传递到 bloc,然后我可以将其传递回 UI。
我试过了: 我希望我能做这样的事情:
BlocProvider.of<TTSPlayerBloc>(context).add(updateCurrentTtsString(currentTtsString));
来自 TTSPlayer 类...当然,这个类不是一个没有上下文的小部件。我应该使用回调吗?什么在这里工作......?我应该将 TTSPlayer 移出该区域并移入屏幕吗?
Stream<TTSPlayerState> mapEventToState(TTSPlayerEvent event) async* {
TTSPlayer lessonPlayer = new TTSPlayer();
if (event is TTSPlayerScreenLoadedEvent) {
//get the script
TTSScript myScript = await scriptRepository.fetchScript(event.script);
// play it
lessonPlayer.play(myLessonScript);
//// How can the lessonplayer inform this Stream every time it's current string has changed?
yield TTSPlayingState();
}
/// something like this??? But how to send this event from TTSPlayer class...
if (event is updateCurrentTtsString){
yield NewStringState(newstring)
}
更新 所以,我在 TTSPlayer 中添加了一个回调。所以这个集团现在看起来像这样:
Stream<TTSPlayerState> mapEventToState(TTSPlayerEvent event) async* {
TTSPlayer lessonPlayer = new TTSPlayer();
///
final newStringCallback = () {
this.add(updateCurrentTtsString(lessonPlayer.currentTtsString));
};
///
if (event is TTSPlayerScreenLoadedEvent) {
//get the script
TTSScript myScript = await scriptRepository.fetchScript(event.script);
// play it
lessonPlayer.play(myLessonScript, newStringCallback););
yield TTSPlayingState();
}
if (event is updateCurrentTtsString) {
print('New String');
yield TTSPlayingState(event.currentString);
}
如果删除 yield 语句,每次 IF 都会触发 updateCurrentStringEvent...当我包含 yield 语句时,它会阻止 TTSPlayer 继续。我不明白为什么玩家会停下来,但确实如此。
【问题讨论】:
标签: flutter text-to-speech bloc