Flutter中如何将ListView.builder生成的ListTile关联跳转至对应音频播放页
实现方案
你只需要调整3个部分即可实现需求:
1. 补充数据模型字段
给你的Item类新增对应音频地址的字段,保证每个列表项和对应音频地址绑定:
class Item { final String name; // 新增字段存储当前条目对应的音频地址 final String audioUrl; Item({required this.name, required this.audioUrl}); }
初始化items数组时给每个条目赋值对应音频地址即可:
final List<Item> items = [ Item(name: "第1章 法蒂哈", audioUrl: "https://download.quranicaudio.com/quran/mishaari_raashid_al_3afaasee/001.mp3"), Item(name: "第2章 黄牛章", audioUrl: "https://download.quranicaudio.com/quran/mishaari_raashid_al_3afaasee/002.mp3"), // 剩余条目依次补充对应音频地址即可 ];
2. 修改列表跳转逻辑,传递参数
调整ListView.builder的点击跳转逻辑,将当前点击条目的名称和音频地址传递给播放页:
ListView.builder( padding: const EdgeInsets.all(8), itemCount: items.length, itemBuilder: (BuildContext context, int index) { final currentItem = items[index]; return ListTile( title: Text(currentItem.name), trailing: const Icon(Icons.play_arrow), onTap: () { Navigator.push( context, MaterialPageRoute( // 传递当前条目对应的参数到播放页 builder: (context) => Audio( audioName: currentItem.name, audioUrl: currentItem.audioUrl, ), ), ); }, ); }, ),
3. 改造音频播放页,动态加载对应资源
删掉原来写死的固定url常量,给Audio组件增加构造参数接收传递的值,同时优化资源释放逻辑避免内存泄漏:
typedef OnError = void Function(Exception exception); class Audio extends StatefulWidget { // 接收跳转时传递的参数 final String audioName; final String audioUrl; const Audio({super.key, required this.audioName, required this.audioUrl}); @override _AudioAppState createState() => _AudioAppState(); } class _AudioAppState extends State<Audio> { final AudioPlayer advancedPlayer = AudioPlayer(); Widget remoteUrl() { return SingleChildScrollView( child: TabWrapper( children: [ Text( // 显示当前音频名称 widget.audioName, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 25), ), // 动态加载当前点击条目的音频 PlayerWidget(url: widget.audioUrl), ], ), ); } @override void dispose() { // 页面销毁时释放音频资源,避免后台继续播放和内存泄漏 advancedPlayer.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return MultiProvider( providers: [ StreamProvider<Duration>.value( initialData: const Duration(), value: advancedPlayer.onAudioPositionChanged, ), ], child: DefaultTabController( length: 1, child: Scaffold( appBar: AppBar( bottom: const TabBar( tabs: [ Tab(text: 'Remote Url'), ], ), title: Center( child: Text( // 页面标题同步显示当前音频名称 widget.audioName, style: const TextStyle(fontSize: 30), ), ), ), body: remoteUrl(), ), ), ); } }
内容的提问来源于stack exchange,提问作者Mike Osborn
相关产品推荐
相关产品推荐

