I have a song playlist screen that includes a list of songs and a navbar for audio play/pause. I set the initial value of the song field as the first element of the songs list, however, when I update the selected song with setState()
, the navbar does not update its song.
class Body extends StatefulWidget {
@override
BodyState createState() => BodyState();
}
class BodyState extends State<Body> {
Music selectedSong = songs[0];
...
@override
Widget build(BuildContext context) {
return Column(
...
Expanded(
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.vertical,
padding: const EdgeInsets.only(top: 20),
itemCount: songs.length,
itemBuilder: (context, i) => songCard(songs[i])
...
MusicBar(music: selectedSong)
For songCard() function:
Widget songCard(Music item) {
return ListTile(
onTap: () => {
setState(() {
selectedSong = item;
})
},
...
When I debug the code, selectedSong
field is updated as expected, however music
field inside MusicBar
is not updated.
For MusicBar class:
class MusicBar extends StatefulWidget {
final Music music;
const MusicBar({Key key, this.music}) : super(key: key);
MusicBarState createState() => MusicBarState(music: music);
}
class MusicBarState extends State<MusicBar> {
final Music music;
MusicBarState({this.music});
AudioPlayer player = AudioPlayer();
@override
void initState() {
super.initState();
// duration = music.duration;
player.onDurationChanged.listen((updatedDuration) {
setState(() {
duration = updatedDuration;
});
});
player.onAudioPositionChanged.listen((updatedPosition) {
setState(() {
position = updatedPosition;
});
});
}
@override
void dispose(){
super.dispose();
player.stop();
player.dispose();
}
@override
Widget build(BuildContext context){
return Container(
...
What did I do wrong so that the MusicBar
widget is not updating?
If needed, songs list is defined outside Body
class, and I am using audioplayers
library
In MusicBarState you can access to music field on Music using widget
. You can refactor you State to:
class MusicBar extends StatefulWidget {
final Music music;
const MusicBar({Key key, this.music}) : super(key: key);
MusicBarState createState() => MusicBarState(); // Empty constructor
}
class MusicBarState extends State<MusicBar> {
// Remove this
// final Music music;
// MusicBarState({this.music});
someMethod() {
// You can access to music using widget:
print(widget.music);
}
// ...
}
Test and check if now works