【问题标题】:Flutter Bloc access from NOT a widget class从非小部件类访问 Flutter Bloc
【发布时间】: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


    【解决方案1】:

    解决方案:

    好的,经过一番折腾,我在集团内部设置了一个新流,如下所示:

      final currentStringStreamController = StreamController<String>();
      StreamSink<String> get currentStringSink => currentStringStreamController.sink;
      Stream<String> get currentStringStream => currentStringStreamController.stream;
    

    然后,在我在原始帖子中设置的回调中,我更改了:

     this.add(updateCurrentTtsString(lessonPlayer.currentTtsString));
    

    到:

      currentStringSink.add(string);
    

    然后使用 async 包中的 darts streambuilder 构建一个文本框小部件。

    希望它可以帮助某人。

    【讨论】:

      猜你喜欢
      • 2019-12-10
      • 2019-10-11
      • 2021-05-19
      • 1970-01-01
      • 2021-06-17
      • 1970-01-01
      • 2020-05-04
      • 2021-07-22
      • 2021-02-20
      相关资源
      最近更新 更多