如何解决ListView中的滑块和图标不一致音频播放器
我正在ListView中实现音频列表,但是在播放时它们确实会播放声音,但是滑块没有变化,只有列表中的第一个是移动的。即使我在列表中播放nth
音频,也只有顶部做出反应。 (播放/暂停图标以及带有搜索功能的滑块)。这是library正在使用。
下面的图片演示了这种情况,我单击了第二个音频,声音是第二个音频的声音,而第一个是正在反应的声音:
我在状态下缺少什么,下面是音频小部件的代码:
class AudioWidget extends StatefulWidget {
final message;
final PlayerState desiredState;
@override
_AudioWidgetState createState() => _AudioWidgetState();
AudioWidget(this.message,this.desiredState);
}
class _AudioWidgetState extends State<AudioWidget> with PlayerObserver {
AudioPlayer audioPlayer = new AudioPlayer();
PlayerState audioPlayerState = PlayerState.STOPPED;
Duration duration = Duration(milliseconds: 1);
Duration currentPlaybackPosition = Duration.zero;
bool _loading = false;
Audio _audioPlayer;
get isPlaying => audioPlayerState == PlayerState.PLAYING;
get isPaused =>
audioPlayerState == PlayerState.PAUSED ||
audioPlayerState == PlayerState.STOPPED;
get durationText =>
duration != null ? duration
.toString()
.split('.')
.first : '';
get positionText =>
currentPlaybackPosition != null
? currentPlaybackPosition
.toString()
.split('.')
.first
: '';
@override
void initState() {
super.initState();
_audioPlayer = Audio.instance();
listenForAudioPlayerEvents();
}
@override
void didUpdateWidget(AudioWidget oldWidget) {
// TODO: implement didUpdateWidget
if (oldWidget.desiredState != widget.desiredState) {
_onDesiredStateChanged(oldWidget);
} else if (oldWidget.message != widget.message) {
play(widget.message);
}
super.didUpdateWidget(oldWidget);
}
/// The [desiredState] flag has changed so need to update playback to
/// reflect the new state.
void _onDesiredStateChanged(AudioWidget oldWidget) async {
switch (widget.desiredState) {
case PlayerState.PLAYING:
play(widget.message);
break;
case PlayerState.PAUSED:
pause();
break;
case PlayerState.STOPPED:
pause();
break;
}
}
@override
void onPlay() {
setState(() {
audioPlayerState = PlayerState.PLAYING;
_loading = false;
});
}
@override
void onPause() {
setState(() {
audioPlayerState = PlayerState.PAUSED;
});
}
@override
void onComplete() {
setState(() {
audioPlayerState = PlayerState.PAUSED;
currentPlaybackPosition = Duration.zero;
});
}
@override
void onTime(int position) {
setState(() {
currentPlaybackPosition = Duration(seconds: position);
});
}
@override
void onSeek(int position,double offset) {
super.onSeek(position,offset);
}
@override
void onDuration(int duration) {
if (duration <= 0) {
setState(() {});
} else {
setState(() {
this.duration = Duration(milliseconds: duration);
});
}
}
@override
void dispose() {
if (mounted) {
_audioPlayer.dispose();
}
super.dispose();
}
Future play(url) async {
setState(() {
_loading = true;
});
await _audioPlayer.play(url,title: "voice note",position: currentPlaybackPosition,isLiveStream: false);
}
// Request audio pause
Future<void> pause() async {
_audioPlayer.pause();
setState(() => audioPlayerState = PlayerState.PAUSED);
}
// Request audio stop. this will also clear lock screen controls
Future<void> stop() async {
_audioPlayer.reset();
setState(() {
audioPlayerState = PlayerState.STOPPED;
currentPlaybackPosition = Duration.zero;
});
}
// Seek to a point in seconds
Future<void> seekTo(double milliseconds) async {
setState(() {
currentPlaybackPosition = Duration(milliseconds: milliseconds.toInt());
});
_audioPlayer.seekTo(milliseconds / 1000);
}
@override
Widget build(BuildContext context) {
print("-- $isPlaying");
return Container(
child: Row(
children: <Widget>[
Material(
child: IconButton(
onPressed: () {
if (isPlaying) {
pause();
} else {
play(widget.message);
}
},icon: isPlaying ? Icon(Icons.pause) : Icon(Icons.play_arrow)),),duration != null
? Slider(
value: currentPlaybackPosition?.inMilliseconds?.toDouble() ??
0.0,onChanged:seekTo,min: 0.0,max: duration.inMilliseconds.toDouble(),activeColor: Colors.red[500],)
: Slider(
value: 0.0,inactiveColor: Colors.red[500],)
],);
}
}
然后,我在列表中调用它以在ListView构建器的另一个有状态Widget中循环它。
我在状态方面缺少什么?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。