I have an application with 100 numbered buttons in GridView. I would like to play corresponding song (named f. e. '87.mp3') after pressing one of the buttons (in this case button 87). The beginning of my AudioPlayer code looks like this:
class AudioPlayer extends StatefulWidget {
final String audioPath;
const AudioPlayer({super.key, required this.audioPath});
@override
_AudioPlayerState createState() => _AudioPlayerState();
}
class _NewCustomWidgetState extends State<AudioPlayer>
with WidgetsBindingObserver {
final _player = AudioPlayer();
@override
void initState() {
super.initState();
ambiguate(WidgetsBinding.instance)!.addObserver(this);
_init();
}
Future<void> _init() async {
final session = await AudioSession.instance;
await session.configure(const AudioSessionConfiguration.speech());
_player.playbackEventStream.listen((event) {},
onError: (Object e, StackTrace stackTrace) {
print('A stream error occurred: $e');
});
try {
await _player.setAsset(widget.audioPath);
print("Audio asset is set.");
} catch (e) {
print("Error loading audio source: $e");
}
}
@override
void dispose() {
ambiguate(WidgetsBinding.instance)!.removeObserver(this);
_player.dispose();
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.paused) {
_player.stop();
}
}
Stream<PositionData> get _positionDataStream =>
Rx.combineLatest3<Duration, Duration, Duration?, PositionData>(
_player.positionStream,
_player.bufferedPositionStream,
_player.durationStream,
(position, bufferedPosition, duration) => PositionData(
position, bufferedPosition, duration ?? Duration.zero));
@override
Widget build(BuildContext context) {...}}
AudioPlayer takes the audioPath as an argument. It notices that audioPath changes, but doesn't update itself, so it plays the same song what was set on the initialization.
let's assume your GridView looks like this:
what you have to do, is that you have to add all your audioPath to an array. and when a button is pressed on the grid, you access the corresponding audioPath using the index of the Grid button. for instance, you taped button 87, the index of that button is provided by the Grid, which it's 86 in the array. so what you have to do is, instead of :
do this:
onTap: () => AudioPlayer(audioPath: arrayOfAudioAssets[index])
// you received the index here:itemBuilder: (_, int index)