Flutter音乐播放器:如何获取迷你播放器当前播放歌曲详情?
解决方案
一、监听播放状态控制迷你播放器显示
通过just_audio的playbackStateStream实时获取播放状态,以此控制底部迷你播放器的显示/隐藏:
// 在State类中定义变量 StreamSubscription<PlaybackState>? _playbackStateSubscription; bool _showMiniPlayer = false; @override void initState() { super.initState(); // 监听播放状态变化 _playbackStateSubscription = player.playbackStateStream.listen((state) { setState(() { // 仅在播放或暂停状态下显示迷你播放器,停止时隐藏 _showMiniPlayer = state.processingState == ProcessingState.playing || state.processingState == ProcessingState.paused; }); }); } @override void dispose() { _playbackStateSubscription?.cancel(); super.dispose(); }
在UI中根据_showMiniPlayer控制显示:
// 底部迷你播放器 Visibility( visible: _showMiniPlayer, child: Container( height: 60, color: Colors.grey[800], child: // 这里放置迷你播放器的内容(歌名、歌手、播放暂停按钮等) ), )
二、获取当前播放歌曲的详情
你的ConcatenatingAudioSource是通过allSongsList映射生成的,当前播放索引与allSongsList的索引完全对应,因此可以通过currentIndexStream获取索引,再从allSongsList中取出对应SongModel拿到歌手、歌名:
// 在State类中添加变量 StreamSubscription<int?>? _currentIndexSubscription; SongModel? _currentSong; @override void initState() { super.initState(); // 监听当前播放索引变化 _currentIndexSubscription = player.currentIndexStream.listen((index) { if (index != null && allSongsList != null && index < allSongsList!.length) { setState(() { _currentSong = allSongsList![index]; }); } }); } @override void dispose() { _currentIndexSubscription?.cancel(); super.dispose(); }
在迷你播放器中直接使用_currentSong的属性:
// 迷你播放器内容示例 Row( children: [ // 歌曲封面(可选,通过on_audio_query获取) FutureBuilder<Uint8List?>( future: AudioQuery().queryArtwork( _currentSong!.id, ArtworkType.AUDIO, ), builder: (context, snapshot) { return snapshot.data != null ? Image.memory(snapshot.data!, width: 50, height: 50) : Icon(Icons.music_note, size: 50); }, ), SizedBox(width: 10), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(_currentSong!.title, style: TextStyle(color: Colors.white)), Text(_currentSong!.artist ?? "未知歌手", style: TextStyle(color: Colors.grey, fontSize: 12)), ], ), Spacer(), // 播放暂停按钮 IconButton( icon: Icon( player.playing ? Icons.pause : Icons.play_arrow, color: Colors.white, ), onPressed: () async { player.playing ? await player.pause() : await player.play(); }, ), ], )
注意事项
- 确保
allSongsList在State类中可访问(可作为成员变量或通过状态管理工具共享) - 处理
allSongsList为空或索引越界的情况,避免空指针异常 - 务必在
dispose中取消所有Stream订阅,防止内存泄漏
内容的提问来源于stack exchange,提问作者Ashish
相关产品推荐
相关产品推荐

