You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
MTMusic/lib/view/music_view_test.dart

508 lines
19 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// music_view_test.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../common/audio_player_controller.dart';
import '../common/download_manager.dart';
import '../common_widget/Song_widegt.dart';
import '../common_widget/app_data.dart';
import 'comment_view.dart';
class MusicView extends StatefulWidget {
final List<Song> songList;
final int initialSongIndex;
final Function(int index, bool isCollected, bool isLiked)?
onSongStatusChanged;
const MusicView({
super.key,
required this.songList,
required this.initialSongIndex,
this.onSongStatusChanged,
});
@override
State<MusicView> createState() => _MusicViewState();
}
class _MusicViewState extends State<MusicView>
with SingleTickerProviderStateMixin {
// late AnimationController _rotationController;
final AudioPlayerController playerController =
Get.put(AudioPlayerController());
final downloadManager = Get.find<DownloadManager>();
final AppData appData = AppData();
@override
void initState() {
super.initState();
playerController.initWithSongs(widget.songList, widget.initialSongIndex);
}
@override
void dispose() {
super.dispose();
}
String formatDuration(Duration duration) {
String twoDigits(int n) => n.toString().padLeft(2, "0");
String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60));
String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60));
return "$twoDigitMinutes:$twoDigitSeconds";
}
Widget _buildProgressSlider() {
return Obx(() {
final max = playerController.duration.value.inSeconds.toDouble() == 0
? 0.1
: playerController.duration.value.inSeconds.toDouble();
final current =
playerController.position.value.inSeconds.toDouble().clamp(0, max);
return SliderTheme(
data: const SliderThemeData(
trackHeight: 3.0,
thumbShape: RoundSliderThumbShape(enabledThumbRadius: 7.0),
overlayShape: RoundSliderOverlayShape(overlayRadius: 12.0),
),
child: Slider(
min: 0,
max: max,
value: current.toDouble(),
onChanged: (value) {
playerController.seekTo(Duration(seconds: value.toInt()));
},
activeColor: const Color(0xff429482),
inactiveColor: const Color(0xffE3F0ED),
),
);
});
}
Widget _buildPlayButton() {
return Obx(() {
return SizedBox(
width: 52,
height: 52,
child: Center(
child: playerController.isLoading.value
? const CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Color(0xff429482)),
strokeWidth: 3.0,
)
: IconButton(
padding: EdgeInsets.zero,
constraints: const BoxConstraints(
minWidth: 52,
minHeight: 52,
maxWidth: 52,
maxHeight: 52,
),
onPressed: playerController.playOrPause,
icon: !playerController.isPlaying.value
? Image.asset(
"assets/img/music_play.png",
width: 52,
height: 52,
)
: Image.asset(
"assets/img/music_pause.png",
width: 52,
height: 52,
),
),
),
);
});
}
// Widget _buildRotatingAlbumCover() {
// return Obx(() {
// final currentSong =
// widget.songList[playerController.currentSongIndex.value];
// return RotationTransition(
// turns: _rotationController,
// child: Stack(
// alignment: Alignment.center,
// children: [
// Positioned(
// child: ClipRRect(
// child: Image.network(
// currentSong.artistPic,
// width: 225,
// height: 225,
// fit: BoxFit.cover,
// ),
// ),
// ),
// ClipRRect(
// child: Image.asset(
// "assets/img/music_Ellipse.png",
// width: 350,
// height: 350,
// fit: BoxFit.cover,
// ),
// ),
// ],
// ),
// );
// });
// }
Widget _buildRotatingAlbumCover() {
return Obx(() {
final currentSong =
widget.songList[playerController.currentSongIndex.value];
// 移除 RotationTransition直接返回静态封面
return Stack(
alignment: Alignment.center,
children: [
Positioned(
child: ClipRRect(
child: Image.network(
currentSong.artistPic,
width: 225,
height: 225,
fit: BoxFit.cover,
),
),
),
ClipRRect(
child: Image.asset(
"assets/img/music_Ellipse.png",
width: 350,
height: 350,
fit: BoxFit.cover,
),
),
],
);
});
}
void _showPlaylist() {
showModalBottomSheet(
context: context,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(30)),
),
builder: (BuildContext context) {
return Container(
padding: const EdgeInsets.only(top: 15),
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height * 0.45,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Center(
child: Text(
"播放列表",
style: TextStyle(fontSize: 20),
),
),
const SizedBox(height: 10),
Expanded(
child: Obx(() => ListView.builder(
itemCount: playerController.musicNames.length,
itemBuilder: (BuildContext context, int index) {
final isCurrentlyPlaying =
playerController.currentSongIndex.value == index;
return ListTile(
tileColor: isCurrentlyPlaying
? const Color(0xffE3F0ED)
: null,
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.only(left: 20),
child: Text(
playerController.musicNames[index],
style: const TextStyle(fontSize: 18),
),
),
Padding(
padding: const EdgeInsets.only(right: 20),
child: Image.asset(
"assets/img/songs_run.png",
width: 25,
),
),
],
),
onTap: () {
playerController.changeSong(index);
Navigator.pop(context);
},
);
},
)),
),
],
),
);
},
);
}
@override
Widget build(BuildContext context) {
return Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/img/app_bg.png"),
fit: BoxFit.cover,
),
),
child: Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Colors.transparent,
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(top: 45, left: 10, right: 10),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
onPressed: () {
Get.back();
},
icon: Image.asset(
"assets/img/back.png",
width: 25,
height: 25,
fit: BoxFit.contain,
),
),
Row(
children: [
IconButton(
onPressed: () {},
icon: Image.asset(
"assets/img/music_add.png",
width: 30,
height: 30,
),
),
Obx(() => IconButton(
onPressed: downloadManager.isDownloading(
playerController.ids[playerController
.currentSongIndex.value]) ||
downloadManager.isCompleted(
playerController.ids[playerController
.currentSongIndex.value])
? null
: () async {
await downloadManager.startDownload(
song: widget.songList[playerController
.currentSongIndex.value],
context: context,
);
},
icon: Obx(() {
if (downloadManager.isDownloading(
playerController.ids[playerController
.currentSongIndex.value])) {
return Stack(
alignment: Alignment.center,
children: [
SizedBox(
width: 32,
height: 32,
child: CircularProgressIndicator(
value: downloadManager.getProgress(
playerController.ids[
playerController
.currentSongIndex.value]),
backgroundColor: Colors.grey[200],
valueColor:
const AlwaysStoppedAnimation<
Color>(Color(0xff429482)),
strokeWidth: 3.0,
),
),
Text(
'${(downloadManager.getProgress(playerController.ids[playerController.currentSongIndex.value]) * 100).toInt()}',
style: const TextStyle(fontSize: 12),
),
],
);
}
return Image.asset(
downloadManager.isCompleted(
playerController.ids[playerController
.currentSongIndex.value])
? "assets/img/music_download_completed.png"
: "assets/img/music_download.png",
width: 30,
height: 30,
);
}),
)),
],
),
],
),
const SizedBox(height: 80),
Center(child: _buildRotatingAlbumCover()),
const SizedBox(height: 60),
Obx(() => Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
playerController.musicName.value,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
Text(
playerController.artistName.value,
style: const TextStyle(fontSize: 20),
),
],
),
Row(
children: [
IconButton(
onPressed: () async {
playerController.toggleLike();
final currentIndex =
playerController.currentSongIndex.value;
widget.onSongStatusChanged?.call(
currentIndex,
playerController.collections[currentIndex],
playerController.likes[currentIndex],
);
},
icon: Image.asset(
playerController.likesStatus.value
? "assets/img/music_good.png"
: "assets/img/music_good_un.png",
width: 29,
height: 29,
),
),
IconButton(
onPressed: () async {
playerController.toggleCollection();
final currentIndex =
playerController.currentSongIndex.value;
widget.onSongStatusChanged?.call(
currentIndex,
playerController.collections[currentIndex],
playerController.likes[currentIndex],
);
},
icon: Image.asset(
playerController.collectionsStatus.value
? "assets/img/music_star.png"
: "assets/img/music_star_un.png",
width: 29,
height: 29,
),
),
IconButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CommentView(
id: playerController.ids[playerController
.currentSongIndex.value],
song: playerController.musicName.value,
singer: playerController.artistName.value,
cover: widget
.songList[playerController
.currentSongIndex.value]
.artistPic,
),
),
);
},
icon: Image.asset(
"assets/img/music_commend_un.png",
width: 29,
height: 29,
),
),
],
),
],
)),
const SizedBox(height: 80),
Obx(() => Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
formatDuration(playerController.position.value),
style: const TextStyle(color: Colors.black),
),
Expanded(child: _buildProgressSlider()),
Text(
formatDuration(playerController.duration.value),
style: const TextStyle(color: Colors.black),
),
],
)),
const SizedBox(height: 30),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
onPressed: () {},
icon: Image.asset(
"assets/img/music_random.png",
width: 35,
height: 35,
),
),
Row(
children: [
IconButton(
onPressed: playerController.playPrevious,
icon: Image.asset(
"assets/img/music_back.png",
width: 42,
height: 42,
),
),
const SizedBox(width: 10),
_buildPlayButton(),
const SizedBox(width: 10),
IconButton(
onPressed: playerController.playNext,
icon: Image.asset(
"assets/img/music_next.png",
width: 42,
height: 42,
),
),
],
),
IconButton(
onPressed: _showPlaylist,
icon: Image.asset(
"assets/img/music_more.png",
width: 35,
height: 35,
),
),
],
),
],
),
),
),
),
);
}
}