[英]Flutter Riverpod : return 2 stream with StreamProvider
I have music player application using package Asset Audio Player and Flutter Riverpod as State Management.我有使用 package资产音频播放器和Flutter Riverpod作为 State 管理的音乐播放器应用程序。 I want listen 2 things stream:
我想听两件事 stream:
final currentSongPosition = StreamProvider.autoDispose<Map<String, dynamic>>((ref) async* {
final AssetsAudioPlayer player = ref.watch(globalAudioPlayers).state;
ref.onDispose(() => player.dispose());
final Stream<double> _first = player.currentPosition.map((event) => event.inSeconds.toDouble());
final Stream<double> _second =
player.current.map((event) => event?.audio.duration.inSeconds.toDouble() ?? 0.0);
final maps = {};
maps['currentDuration'] = _first;
maps['maxDurationSong'] = _second;
return maps; << Error The return type 'Map<dynamic, dynamic>' isn't a 'Stream<Map<String, dynamic>>', as required by the closure's context.
});
How can i return 2 stream into 1 StreamProvider
then i can simply using like this:我怎样才能将 2 stream 返回到 1
StreamProvider
然后我可以像这样简单地使用:
Consumer(
builder: (_, watch, __) {
final _currentSong = watch(currentSongPosition);
return _currentSong.when(
data: (value) {
final _currentDuration = value['currentDuration'] as double;
final _maxDuration = value['maxDuration'] as double;
return Text('Current : $_currentDuration, Max :$_maxDuration');
},
loading: () => Center(child: CircularProgressIndicator()),
error: (error, stackTrace) => Text('Error When Playing Song'),
);
},
),
I would start by creating a StreamProvider
for each Stream
:我将从为每个
Stream
创建一个StreamProvider
开始:
final currentDuration = StreamProvider.autoDispose<double>((ref) {
final player = ref.watch(globalAudioPlayers).state;
return player.currentPosition.map((event) => event.inSeconds.toDouble());
});
final maxDuration = StreamProvider.autoDispose<double>((ref) {
final player = ref.watch(globalAudioPlayers).state;
return player.current.map((event) => event?.audio.duration.inSeconds.toDouble() ?? 0.0);
});
Next, create a FutureProvider
to read the last value of each Stream
.接下来,创建一个
FutureProvider
来读取每个Stream
的最后一个值。
final durationInfo = FutureProvider.autoDispose<Map<String, double>>((ref) async {
final current = await ref.watch(currentDuration.last);
final max = await ref.watch(maxDuration.last);
return {
'currentDuration': current,
'maxDurationSong': max,
};
});
Finally, create a StreamProvider
that converts durationInfo
into a Stream
.最后,创建一个
StreamProvider
将durationInfo
转换为Stream
。
final currentSongPosition = StreamProvider.autoDispose<Map<String, double>>((ref) {
final info = ref.watch(durationInfo.future);
return info.asStream();
});
This answer is another approach what @AlexHartford do.
这个答案是@AlexHartford 所做的另一种方法。
Current solution for my case is using package rxdart CombineLatestStream.list()
, this code should be look then:我的案例的当前解决方案是使用 package rxdart
CombineLatestStream.list()
,然后应该查看此代码:
final currentSongPosition = StreamProvider.autoDispose((ref) {
final AssetsAudioPlayer player = ref.watch(globalAudioPlayers).state;
final Stream<double> _first = player.currentPosition.map((event) => event.inSeconds.toDouble());
final Stream<double> _second =
player.current.map((event) => event?.audio.duration.inSeconds.toDouble() ?? 0.0);
final tempList = [_first, _second];
return CombineLatestStream.list(tempList);
});
Consumer(
builder: (_, watch, __) {
final players = watch(globalAudioPlayers).state;
final _currentSong = watch(currentSongPosition);
return _currentSong.when(
data: (value) {
final _currentDuration = value[0];
final _maxDuration = value[1];
return Slider.adaptive(
value: _currentDuration,
max: _maxDuration,
onChanged: (value) async {
final newDuration = Duration(seconds: value.toInt());
await players.seek(newDuration);
context.read(currentSongProvider).setDuration(newDuration);
},
);
},
loading: () => const Center(child: CircularProgressIndicator()),
error: (error, stackTrace) => Text(error.toString()),
);
},
),
But this approach have drawback, the code is hard to readable.
但是这种方法有缺点,代码难以阅读。 Especially when use in
Consumer
, I have to know the order of return result.特别是在
Consumer
中使用时,我必须知道返回结果的顺序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.