I am using Slider.adaptive
in bottomsheet but it does not update my view regardless that I am using StatefulBuilder
.
Here is minimized version of my code:
Duration _duration = const Duration(milliseconds: 0);
Duration _position = const Duration(milliseconds: 0);
@override
Widget build(BuildContext context) {
return PopScope(
canPop: false,
onPopInvoked: (bool didPop) async {
if (isPlaying == true) {
setState(() async {
await audioPlayer.stop();
});
}
},
child: Scaffold(
body: SafeArea(
child: Center(
child: Text('Testing Screen'),
)
),
bottomNavigationBar: BottomAppBar(
padding: EdgeInsets.zero,
color: Colors.black,
height: 130,
child: Column(
children: [
IconButton(
icon: const FaIcon(
FontAwesomeIcons.headphones,
color: Colors.white70,
),
onPressed: () async {
_openAudioBottomSheet();
},
),
]
),
),
),
);
}
void _openAudioBottomSheet() {
showModalBottomSheet(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(20.0)),
),
context: context,
showDragHandle: true,
builder: (BuildContext context) {
return StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Slider.adaptive(
min: 0,
max: _duration.inSeconds.toDouble(),
value: _position.inSeconds.toDouble(),
onChanged: (value) async {
debugPrint('value is:: $value');
setState(() {
_position = Duration(seconds: value.toInt());
});
},
),
],
),
),
);
}
);
}
);
}
Any idea of how to make this view update works?
Update
I’ve noticed one thing just now, problem is most likely caused by _position
data not passing to showModalBottomSheet
rather than onChanged
method issue!
It seems _position
will not get updated duration in bottom sheet therefore slider doesn’t move forward.
here is my audioplayer initialization code:
@override
void initState() {
super.initState();
initAudioPlayer();
}
initAudioPlayer() async {
audioPlayer.setAudioContext(
const AudioContext(
android: AudioContextAndroid(),
iOS: AudioContextIOS(),
)
);
audioPlayer.onPlayerStateChanged.listen((PlayerState event) {
setState(() {
isPlaying = event == PlayerState.playing;
audioPlayer.setVolume(_volume);
if (PlayerState == PlayerState.completed || PlayerState == PlayerState.stopped || PlayerState == PlayerState.paused) {
setState(() {
isLoading = false; // Loading is complete
});
} else if (PlayerState == PlayerState.playing) {
setState(() {
isLoading = true; // Audio loading is in progress
});
}
});
});
audioPlayer.onDurationChanged.listen((Duration event) {
setState(() {
_duration = event;
});
});
audioPlayer.onPositionChanged.listen((Duration event) {
// this does get updated, but wont pass to bottomsheet!
debugPrint('value is: $event');
setState(() {
_position = event;
});
});
}
3
Answers
The reason it is not updating because the
max
andmin
are same which is zero.Another noticeable thing is, you have define millisecond on but using as second, have the same format will make it more readable.
using this one changed to Statefull Builder position and showBottomSheet instead of showModelBottomSheet
You are using an audio player library, and you’ve correctly identified that the issue might be related to _position not getting updated in the showModalBottomSheet. This could be due to the fact that the showModalBottomSheet creates a separate context for the bottom sheet, and the state might not be properly passed.
By passing _position as a parameter to _openAudioBottomSheet and using it as the initial value for the slider, you ensure that the correct position is set in the bottom sheet.