You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 06:57:02