简体   繁体   English

flutter 中的相同 StreamBuilders,一个正在工作,另一个返回 null

[英]Identical StreamBuilders in flutter, one is working other returns null

I have two identical stream builders in two different widgets.我在两个不同的小部件中有两个相同的 stream 构建器。 One works, while the other is receiving no data.一个工作,而另一个不接收数据。 This is the widget tree.这是小部件树。

在此处输入图像描述

Here is the StreamBuilder这是StreamBuilder

StreamBuilder<AudioPlayerState>(
    stream: _playbackProvider.playbackState,
    builder: (context, snapshot) {
      IconData _playbackButton = Icons.play_circle_filled;

         if (snapshot.hasData) {
             if (snapshot.data == AudioPlayerState.PLAYING) {
                  _playbackButton = Icons.pause_circle_filled;
             } else {
                  _playbackButton = Icons.play_circle_filled;
             }
         }

        return OutlineButton(
             onPressed: () {
               _playButtonClicked(snapshot.data);
             },
             child: Icon(_playbackButton),
             shape: CircleBorder(),
        );
}),

Here is the stream they are both listening to:这是他们都在听的 stream:

Stream<AudioPlayerState> get playbackState {
    return _audioPlayer.onPlayerStateChanged; // using onPlayerStateChanged stream provided by audioplayers plugin.
}

This stream can be accessed by the change notifier provider, in both of these widgets (Scaffolds).这个 stream 可以由更改通知提供程序在这两个小部件(脚手架)中访问。 The audioplayer is enclosed in a ChangeNotifier class.音频播放器包含在 ChangeNotifier class 中。

class PlaybackProvider with ChangeNotifier {
  String _path;
  AudioPlayer _audioPlayer;

  PlaybackProvider() {
    _audioPlayer = AudioPlayer();
    _audioPlayer.setReleaseMode(ReleaseMode.STOP);
    _audioPlayer.notificationState = AudioPlayerState.STOPPED;
  }

  Stream<Duration> get playbackPosition { // this stream is also working fine in the first screen (widget)
    return _audioPlayer.onAudioPositionChanged;
  }

  Stream<AudioPlayerState> get playbackState {
    return _audioPlayer.onPlayerStateChanged;
  }

//other methods
}

The change notifier is then provided to each of these widgets.然后将更改通知器提供给这些小部件中的每一个。

final _playbackProvider = Provider.of<PlaybackProvider>(context);

And the main function,和主要的function,

void main() {
  runApp(MultiProvider(providers: [
    ChangeNotifierProvider(create: (_) => PlaylistProvider()),
    ChangeNotifierProvider(create: (_) => PlaybackProvider()),
  ], child: MyApp()));
}
Stream<Duration> get playbackPosition { // this stream is also working fine in the first screen (widget)
    return _audioPlayer.onAudioPositionChanged;
  }

Are you sure _audioPlayer.onAudioPositionChanged is a BroadcastStream or that it returns the same instance of Strem, It could be the case that the getter is returning different instances each time you call it, one way to be sure you have the same value is to create a StreamProvider and then consume it down in the tree您确定 _audioPlayer.onAudioPositionChanged 是一个 BroadcastStream 还是它返回相同的 Strem 实例,可能是每次调用它时 getter 返回不同的实例,确保您具有相同值的一种方法是创建一个 StreamProvider,然后在树中使用它

void main() {
  runApp(MultiProvider(providers: [
    ChangeNotifierProvider(create: (_) => PlaylistProvider()),
    ChangeNotifierProvider(create: (_) => PlaybackProvider()),
    StreamProvider<AudioPlayerState>(create: (context) => Provider.of<PlaybackProvider>(context, listen: false).playbackState)
  ], child: MyApp()));
}

And then instead of StreamBuilder in each widget just use the consumer然后在每个小部件中而不是 StreamBuilder 只使用消费者

return OutlineButton(
  onPressed: () => _playButtonClicked(snapshot.data),
  child: Consumer<AudioPlayerState>(
    builder: (context, data, _) {
      if(data  == AudioPlayerState.PLAYING) return Icon(Icons.pause_circle_filled);
      return Icon(Icons.play_circle_filled);
    }
  ),
  shape: CircleBorder(),
);

Your code and logic is not wrong, but if you're using provider maybe it's better to use all the kind of Providers it provides (unironically) to your advantage.您的代码和逻辑没有错,但是如果您使用提供者,最好使用它提供的所有类型的提供者(讽刺地)对您有利。 If you want to keep with the StreamBuilder, that's fine too, but without seeing your code of AudioPlayer class it's hard to se what is returning _audioPlayer.onAudioPositionChanged , if it's a simple stream, are you creating it anew in that method, its Broadcast (using the asBroadCast method), etc?如果您想继续使用 StreamBuilder,那也可以,但是如果没有看到您的AudioPlayer class 代码,则很难确定返回_audioPlayer.onAudioPositionChanged的内容,如果它是一个简单的 stream,您是在重新创建它的广播方法吗?使用 asBroadCast 方法)等?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM