![](/img/trans.png)
[英]Flutter: Using 2 nested StreamBuilders where one of them is not working as expected
[英]Identical StreamBuilders in flutter, one is working other returns null
我在兩個不同的小部件中有兩個相同的 stream 構建器。 一個工作,而另一個不接收數據。 這是小部件樹。
這是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:
Stream<AudioPlayerState> get playbackState {
return _audioPlayer.onPlayerStateChanged; // using onPlayerStateChanged stream provided by audioplayers plugin.
}
這個 stream 可以由更改通知提供程序在這兩個小部件(腳手架)中訪問。 音頻播放器包含在 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
}
然后將更改通知器提供給這些小部件中的每一個。
final _playbackProvider = Provider.of<PlaybackProvider>(context);
和主要的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;
}
您確定 _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()));
}
然后在每個小部件中而不是 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(),
);
您的代碼和邏輯沒有錯,但是如果您使用提供者,最好使用它提供的所有類型的提供者(諷刺地)對您有利。 如果您想繼續使用 StreamBuilder,那也可以,但是如果沒有看到您的AudioPlayer
class 代碼,則很難確定返回_audioPlayer.onAudioPositionChanged
的內容,如果它是一個簡單的 stream,您是在重新創建它的廣播方法嗎?使用 asBroadCast 方法)等?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.