I'm implementing the function of playing the list of recorded files in list. When the playback is complete, run play next file.
I update to setState() when the playback is completed. And each time use setState(), I used play() function inside the build() method to recall play().
However, the method in the build is called twice, so the audio file is also played twice.
How do I run this method only once when I build it?
class PlayingScreen extends StatefulWidget {
final PostModel postModel;
PlayingScreen({
Key? key,
required this.postModel,
}) : super(key: key);
@override
State<PlayingScreen> createState() => _PlayingScreenState();
}
class _PlayingScreenState extends State<PlayingScreen> {
final _audioPlayer = AudioPlayer();
List<String> _audios = []; // audio file path list
int _playIndex = 0;
@override
void initState() {
_getAudios();
super.initState();
}
@override
void dispose() {
_audioPlayer.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
_play(_playIndex);
return Scaffold(
appBar: AppBar(
title: Text(widget.postModel.title),
),
body: InkWell(
onTap: () {
Get.back();
},
// image widget
),
),
);
}
Future _play(int index) async {
await _audioPlayer.play(DeviceFileSource(_audios[index]));
logger.d("current index: $_playIndex / ${_audios.length - 1}");
//complete event
_audioPlayer.onPlayerComplete.listen((event) {
logger.d("complet, next");
setState(() {
if (_playIndex >= _imageSets.length - 1) {
_playIndex = 0;
logger.d("return first index");
} else {
_playIndex ;
}
});
});
}
}
CodePudding user response:
// ...
int _playIndex = 0;
bool played = false
// ...
// build
if(! played) {
_play(_playIndex);
played = true;
}
- Add the variable "played" at the class level
- Add a check in the build method
CodePudding user response:
Calling a future inside the build method will always rebuild multiple times not only twice.
I would probably use it in a FutureBuilder()
like so:
FutureBuilder(
future:_play(_playIndex),
builder:(context, snapshot){
...
}
)