flutter - Flutter Riverpod:使用 StreamProvider 返回 2 个流
问题描述
我有使用包Asset Audio Player和Flutter Riverpod作为状态管理的音乐播放器应用程序。我想听两件事流:
- 收听歌曲的当前时长
- 收听当前播放的歌曲
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.
});
如何将 2 个流返回 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'),
);
},
),
解决方案
我将首先StreamProvider
为每个创建一个Stream
:
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);
});
接下来,创建一个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,
};
});
最后,创建一个StreamProvider
转换durationInfo
为Stream
.
final currentSongPosition = StreamProvider.autoDispose<Map<String, double>>((ref) {
final info = ref.watch(durationInfo.future);
return info.asStream();
});
推荐阅读
- python - 使用 Oozie 调度具有依赖项的 Python 脚本
- flutter - 颤动中gridview项目上的动画
- php - 如何逃避 Codeigniter 语言功能?
- android - Fragment与ViewLifecycleOwner的偏差
- c - 如何在运行时打印 .so 文件位置?
- c - 使用 nanosleep 在 c 代码中利用小停顿的问题
- c# - 作为 Func 的参数传递时的异步方法
Wrapper 方法中的占位符我得到编译错误 - git - 如何更改合并操作中使用的 Gitlab 中的 core.autocrlf?
- javascript - Javascript heap out of memory 永久解决方案
- html - html5 中的视频不适用于所有浏览器