Flutter音频播放器:如何实现单个按钮控制播放/暂停状态
实现可控制音频播放/暂停按钮的具体方案
1. 添加音频播放依赖
先在项目的pubspec.yaml中引入音频处理库,这里使用audioplayers:
dependencies: flutter: sdk: flutter audioplayers: ^4.0.1 # 建议使用最新版本
执行flutter pub get完成依赖安装。
2. 改造代码实现状态控制
因为需要跟踪每个列表项的播放状态,要把原Widget改为StatefulWidget,同时维护播放状态和音频播放器实例:
import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/material.dart'; class RadioListScreen extends StatefulWidget { final List<RadioDetail> radioDetails; // 你的电台数据模型类 const RadioListScreen({super.key, required this.radioDetails}); @override State<RadioListScreen> createState() => _RadioListScreenState(); } class _RadioListScreenState extends State<RadioListScreen> { // 记录每个列表项的播放状态,初始全为未播放 late List<bool> _isPlayingList; // 音频播放器实例,若要支持多音频同时播放,可改为Map<int, AudioPlayer> final AudioPlayer _audioPlayer = AudioPlayer(); // 记录当前正在播放的列表项索引,避免多音频同时播放 int? _currentPlayingIndex; @override void initState() { super.initState(); // 初始化播放状态列表,长度与电台数据一致 _isPlayingList = List.filled(widget.radioDetails.length, false); } @override void dispose() { // 页面销毁时释放音频资源,防止内存泄漏 _audioPlayer.dispose(); super.dispose(); } // 播放/暂停切换逻辑 Future<void> _togglePlayPause(int index) async { final targetRadio = widget.radioDetails[index]; setState(() { if (_currentPlayingIndex == index) { // 点击的是正在播放的项,切换暂停/播放状态 _isPlayingList[index] = !_isPlayingList[index]; } else { // 点击的是未播放的项,先停止之前的播放项 if (_currentPlayingIndex != null) { _isPlayingList[_currentPlayingIndex!] = false; } _isPlayingList[index] = true; _currentPlayingIndex = index; } }); if (_isPlayingList[index]) { // 开始播放,假设你的RadioDetail类有audioUrl字段存储音频地址 await _audioPlayer.play(UrlSource(targetRadio.audioUrl)); } else { // 暂停播放 await _audioPlayer.pause(); _currentPlayingIndex = null; } } @override Widget build(BuildContext context) { return Scaffold( appBar: const AppBar(title: Text("ListView.builder")), body: ListView.builder( itemCount: widget.radioDetails.length, itemBuilder: (BuildContext context, int index) { return Card( clipBehavior: Clip.antiAlias, child: ListTile( title: Text(widget.radioDetails[index].name), trailing: IconButton( // 根据播放状态切换图标 icon: Icon( _isPlayingList[index] ? Icons.pause : Icons.play_arrow, color: Colors.blue, ), onPressed: () => _togglePlayPause(index), ), ), ); }, ), ); } } // 假设你的电台数据模型类 class RadioDetail { final String name; final String audioUrl; RadioDetail({required this.name, required this.audioUrl}); }
核心逻辑说明
- 状态跟踪:用
_isPlayingList数组记录每个列表项的播放状态,_currentPlayingIndex标记当前播放项,避免多音频同时播放。 - 切换逻辑:点击按钮时,若当前项未播放则启动播放并停止之前的播放项;若当前项正在播放则暂停。
- 资源管理:在页面销毁时释放音频播放器资源,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Afthal Ad
相关产品推荐
相关产品推荐

