我在两个不同的小部件中有两个相同的流生成器。一个有效,而另一个不接收任何数据。这是小部件树。
这是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(),
);
}),
这是他们俩都在听的流:Stream<AudioPlayerState> get playbackState {
return _audioPlayer.onPlayerStateChanged; // using onPlayerStateChanged stream provided by audioplayers plugin.
}
变更通知程序提供者可以在这两个小部件(脚手架)中访问此流。音频播放器包含在ChangeNotifier类中。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
}
然后将更改通知程序提供给这些小部件中的每个。final _playbackProvider = Provider.of<PlaybackProvider>(context);
还有主要功能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;
}
您确定_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()));
}
然后,使用每个使用者代替每个小部件中的StreamBuilderreturn 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(),
);
您的代码和逻辑没有错,但是如果您使用提供程序,则最好(单反)使用它提供的所有类型的提供程序都对您有利。如果您想继续使用StreamBuilder,那也很好,但是如果看不到AudioPlayer
类的代码,则很难确定返回的_audioPlayer.onAudioPositionChanged
的内容,如果它是简单的流,是否要在该方法中重新创建它,即Broadcast(使用asBroadCast方法)等?
关于flutter - 相同的StreamBuilders处于波动状态,一个正在工作而其他返回null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62689123/