Dart中如何从返回Future<List<Audio>>的函数中获取实际Audio列表
解决方案
你对FutureBuilder的使用存在误解,它并不要求传入的Future返回Widget类型。FutureBuilder本质是异步状态监听组件,你只需要在其builder回调中,根据异步返回的Audio列表数据,自行构建需要的Widget或者执行播放器初始化逻辑即可。
场景1:异步加载后同时渲染播放列表UI + 初始化播放器
直接使用FutureBuilder处理异步逻辑即可,示例代码如下:
final AssetsAudioPlayer _player = AssetsAudioPlayer.instance; // 提前缓存Future,避免重复请求 late Future<List<Audio>> _audioListFuture; @override void initState() { super.initState(); _audioListFuture = creaLista(); } @override Widget build(BuildContext context) { return Scaffold( body: FutureBuilder<List<Audio>>( future: _audioListFuture, builder: (context, snapshot) { // 加载中状态 if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } // 加载出错状态 if (snapshot.hasError) { return Center(child: Text('加载播放列表失败:${snapshot.error}')); } // 加载成功,拿到Audio列表 final audioList = snapshot.data!; // 给播放器设置全局播放列表 _player.open( Playlist(audios: audioList), autoStart: false, showNotification: true, ); // 基于Audio列表的元数据渲染歌曲列表UI return ListView.builder( itemCount: audioList.length, itemBuilder: (context, index) { final meta = audioList[index].metas; return ListTile( leading: Image.network(meta.image?.path ?? '', width: 50, height: 50, fit: BoxFit.cover), title: Text(meta.title ?? '未知歌曲'), subtitle: Text(meta.artist ?? '未知歌手'), onTap: () { // 点击播放对应位置的歌曲 _player.playlistPlayAtIndex(index); }, ); }, ); }, ), ); }
场景2:无需绑定UI,预加载播放列表供全局调用
如果不需要用Audio列表直接渲染UI,可以在State生命周期中提前加载并缓存Audio列表,示例代码如下:
List<Audio>? _audioList; final AssetsAudioPlayer _player = AssetsAudioPlayer.instance; @override void initState() { super.initState(); _loadAudioList(); } Future<void> _loadAudioList() async { try { // 异步加载Audio列表 _audioList = await creaLista(); // 加载完成后直接初始化播放列表 await _player.open( Playlist(audios: _audioList!), autoStart: false, ); } catch(e) { // 自定义异常处理逻辑,比如弹出Toast提示 debugPrint('加载播放列表失败:$e'); } }
注意事项
- 建议在
creaLista()方法中补充异常捕获逻辑,覆盖网络请求失败、JSON解析异常等边界情况,避免应用无响应。 - 如果你的应用需要全局使用这个播放列表,可以将Audio列表缓存到全局状态管理中(比如Provider、Bloc等),避免跨页面重复请求。
内容的提问来源于stack exchange,提问作者Nicholas Piastrella
相关产品推荐
相关产品推荐

