//这里的方法就是:可以先在Widget build写一部分,用Expanded把Material的控件放底下,然后再用Material(child: _buildPlayer()),显示其他界面,可以在_buildPlayer方法体里面放其他方法体,可以用列的方式排序,方法体的写法要学会 方法体如下
Row _buildMuteButtons() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
if (!isMuted)
FlatButton.icon(
onPressed: () => mute(true),
icon: Icon(
Icons.headset_off,
color: Colors.cyan,
),
label: Text('Mute', style: TextStyle(color: Colors.cyan)),
),
if (isMuted)
FlatButton.icon(
onPressed: () => mute(false),
icon: Icon(Icons.headset, color: Colors.cyan),
label: Text('Unmute', style: TextStyle(color: Colors.cyan)),
),
],
);
}
import 'dart:async';
import 'package:audioplayer/audioplayer.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
typedef void OnError(Exception exception);
const kUrl = "https://s3.amazonaws.com/scifri-segments/scifri201711241.mp3";
enum PlayerState { stopped, playing, paused }
class AudioPlay extends StatefulWidget {
const AudioPlay({Key key}) : super(key: key);
@override
_AudioPlayState createState() => _AudioPlayState();
}
class _AudioPlayState extends State<AudioPlay> {
Duration duration;
Duration position;
AudioPlayer audioPlayer;
String localFilePath;
PlayerState playerState = PlayerState.stopped;
get isPlaying => playerState == PlayerState.playing;
get isPaused => playerState == PlayerState.paused;
get durationText =>
duration != null ? duration.toString().split('.').first : '';
get positionText =>
position != null ? position.toString().split('.').first : '';
bool isMuted = false;
StreamSubscription _positionSubscription;
StreamSubscription _audioPlayerStateSubscription;
@override
void initState() {
super.initState();
initAudioPlayer();
}
@override
void dispose() {
_positionSubscription.cancel();
_audioPlayerStateSubscription.cancel();
audioPlayer.stop();
super.dispose();
}
void initAudioPlayer() {
audioPlayer = AudioPlayer();
_positionSubscription = audioPlayer.onAudioPositionChanged
.listen((p) => setState(() => position = p));
_audioPlayerStateSubscription =
audioPlayer.onPlayerStateChanged.listen((s) {
if (s == AudioPlayerState.PLAYING) {
setState(() => duration = audioPlayer.duration);
} else if (s == AudioPlayerState.STOPPED) {
onComplete();
setState(() {
position = duration;
});
}
}, onError: (msg) {
setState(() {
playerState = PlayerState.stopped;
duration = Duration(seconds: 0);
position = Duration(seconds: 0);
});
});
}
Future play() async {
await audioPlayer.play(kUrl);
setState(() {
playerState = PlayerState.playing;
});
}
Future _playLocal() async {
await audioPlayer.play(localFilePath, isLocal: true);
setState(() => playerState = PlayerState.playing);
}
Future pause() async {
await audioPlayer.pause();
setState(() => playerState = PlayerState.paused);
}
Future stop() async {
await audioPlayer.stop();
setState(() {
playerState = PlayerState.stopped;
position = Duration();
});
}
Future mute(bool muted) async {
await audioPlayer.mute(muted);
setState(() {
isMuted = muted;
});
}
void onComplete() {
setState(() => playerState = PlayerState.stopped);
}
@override
Widget build(BuildContext context) {
final textTheme = Theme.of(context).textTheme;
return Center(
child: Center(
child: Container(
decoration: BoxDecoration(color: Color(0xFF1F1F1F)),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Expanded(
child: Column(
children: [
Container(
child: Text(
'',
),
),
Container(
margin: const EdgeInsets.only(left: 15, right: 15),
child: Image.asset(
'assets/base_widgets/bg_player.png',
fit: BoxFit.fitWidth,
),
),
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: const EdgeInsets.only(
left: 30, top: 30, bottom: 15),
child: Text("Mojito",
style: TextStyle(
color: Color(0xFFCCCCCC), fontSize: 20)),
),
Row(
children: [
Container(
margin:
const EdgeInsets.only(left: 30, bottom: 12),
child: Text(
"周杰倫",
style: TextStyle(color: Color(0xFF999999)),
),
),
Container(
width: 30,
margin:
const EdgeInsets.only(left: 15, bottom: 12),
child: Image.asset(
'assets/base_widgets/icon_player_vip.png',
fit: BoxFit.fitWidth,
),
),
Container(
width: 30,
margin:
const EdgeInsets.only(left: 15, bottom: 12),
child: Image.asset(
'assets/base_widgets/icon_player_standard.png',
fit: BoxFit.fitWidth,
),
),
],
),
Container(
margin: const EdgeInsets.only(left: 30, bottom: 12),
child: Text("麻烦给我的爱人来一杯Mojito",
style: TextStyle(color: Color(0xFF666666))),
),
Container(
margin: const EdgeInsets.only(left: 30, bottom: 12),
child: Text("我喜欢阅读她微醺时的眼眸",
style: TextStyle(color: Color(0xFFFFFFFF))),
),
Container(
margin: const EdgeInsets.only(left: 30, bottom: 12),
child: Text("而我的咖啡糖不用太多",
style: TextStyle(color: Color(0xFF666666))),
),
],
),
),
],
),
),
Material(child: _buildPlayer()),
if (!kIsWeb)
localFilePath != null ? Text(localFilePath) : Container(),
],
),
),
),
);
}
Widget _buildPlayer() => Container(
decoration: BoxDecoration(color: Color(0xFF1F1F1F)),
padding: EdgeInsets.all(16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
buttonMenuSection(),
if (duration != null)
Slider(
value: position?.inMilliseconds?.toDouble() ?? 0.0,
onChanged: (double value) {
return audioPlayer.seek((value / 1000).roundToDouble());
},
min: 0.0,
max: duration.inMilliseconds.toDouble()),
if (duration == null)
Slider(
value: position?.inMilliseconds?.toDouble() ?? 0.0,
),
_buildProgressView(),
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: 40,
margin: const EdgeInsets.only(left: 15, right: 15),
child: Image.asset(
'assets/base_widgets/icon_player_cycle.png',
fit: BoxFit.fitWidth,
),
),
GestureDetector(
onTap: isPlaying ? () => pause() : () => play(),
child: Container(
width: 40,
margin: const EdgeInsets.only(left: 15, right: 15),
child: Image.asset(
'assets/base_widgets/icon_player_previous.png',
fit: BoxFit.fitWidth,
),
),
),
GestureDetector(
onTap: isPlaying ? () => pause() : () => play(),
child: Container(
width: 50,
margin: const EdgeInsets.only(left: 15, right: 15),
child: Image.asset(
'assets/base_widgets/icon_player_play.png',
fit: BoxFit.fitWidth,
),
),
),
GestureDetector(
onTap: isPlaying ? () => pause() : () => play(),
child: Container(
width: 40,
margin: const EdgeInsets.only(left: 15, right: 15),
child: Image.asset(
'assets/base_widgets/icon_player_next.png',
fit: BoxFit.fitWidth,
),
),
),
Container(
width: 40,
margin: const EdgeInsets.only(left: 15, right: 15),
child: Image.asset(
'assets/base_widgets/icon_player_tuning.png',
fit: BoxFit.fitWidth,
),
),
]),
],
),
);
Row _buildProgressView() =>
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Container(
margin: const EdgeInsets.only(left: 15),
child: Text(
position != null
? "${positionText ?? ''} "
: duration != null
? durationText
: '',
style: TextStyle(fontSize: 12.0, color: Colors.white),
),
),
Container(
margin: const EdgeInsets.only(left: 15),
child: Text(
position != null
? "${durationText ?? ''}"
: duration != null
? durationText
: '',
style: TextStyle(fontSize: 12.0, color: Colors.white),
)),
]);
Row _buildMuteButtons() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
if (!isMuted)
FlatButton.icon(
onPressed: () => mute(true),
icon: Icon(
Icons.headset_off,
color: Colors.cyan,
),
label: Text('Mute', style: TextStyle(color: Colors.cyan)),
),
if (isMuted)
FlatButton.icon(
onPressed: () => mute(false),
icon: Icon(Icons.headset, color: Colors.cyan),
label: Text('Unmute', style: TextStyle(color: Colors.cyan)),
),
],
);
}
Column menuButtonColumn(String icon, String label) {
Color color = const Color(0xFF999999);
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
icon,
height: 45.0,
fit: BoxFit.cover,
),
Container(
margin: const EdgeInsets.only(top: 8.0),
child: Text(
label,
style: TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.w400,
color: color,
),
),
)
],
);
}
Row buttonMenuSection() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
menuButtonColumn("assets/base_widgets/icon_player_cover.png", '翻唱'),
menuButtonColumn(
"assets/base_widgets/icon_player_equalizer.png", '均衡器'),
menuButtonColumn(
"assets/base_widgets/icon_player_member_download.png", '下載'),
menuButtonColumn("assets/base_widgets/icon_player_comment.png", '評論'),
menuButtonColumn("assets/base_widgets/icon_player_more.png", '更多'),
],
);
}
}
|