import 'dart:io'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:music_player_miao/api/api_songlist.dart'; import 'package:music_player_miao/common_widget/app_data.dart'; import 'package:music_player_miao/models/songlist_bean.dart'; import 'package:music_player_miao/models/universal_bean.dart'; import 'package:music_player_miao/view/begin/begin_view.dart'; import 'package:music_player_miao/view/user/my_download_view.dart'; import 'package:music_player_miao/view/user/my_music_view.dart'; import 'package:music_player_miao/view/user/user_info.dart'; import 'package:music_player_miao/widget/text_field.dart'; import '../../../view_model/home_view_model.dart'; import '../../api/api_client.dart'; import '../../common/download_manager.dart'; import '../../models/search_bean.dart'; import 'my_work_view.dart'; class UserView extends StatefulWidget { const UserView({super.key}); @override State createState() => _UserViewState(); } class _UserViewState extends State { final homeVM = Get.put(HomeViewModel()); final TextEditingController _controller = TextEditingController(); int playlistCount = 0; List playlistNames = []; List playlistid = []; int downloadCount = 0; String avatar = AppData().currentAvatar; String username = AppData().currentUsername; final downloadManager = Get.put(DownloadManager()); @override void initState() { super.initState(); _fetchSonglistData(); downloadCount = downloadManager.completedNumber(); } Future _fetchSonglistData() async { try { SearchBean bean2 = await SonglistApi().getSonglist( Authorization: AppData().currentToken, ); setState(() { playlistNames = bean2.data!.map((data) => data.name!).toList(); playlistid = bean2.data!.map((data) => data.id!).toList(); // 确保这里的id是int类型 playlistCount = playlistNames.length; }); } catch (error) { print('Error fetching songlist data: $error'); } } @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(left: 15, right: 15, top: 55), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ///头部--头像、昵称、下弹框 Padding( padding: const EdgeInsets.only(left: 15, right: 10, bottom: 30), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Image.network( avatar, width: 64, height: 64, ), const SizedBox( width: 25, ), Text( username, style: const TextStyle(fontSize: 20), ) ], ), IconButton( onPressed: () { _bottomSheet(context); }, icon: Image.asset("assets/img/user_more.png")) ], ), ), ///我的音乐库 const Text( '我的音乐库', style: TextStyle(fontSize: 20, fontWeight: FontWeight.w500), ), Container( padding: const EdgeInsets.only( left: 15, right: 15, top: 20, bottom: 20), //我的收藏 child: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ InkWell( onTap: () { Get.to(const MyMusicView()); }, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Image.asset("assets/img/artist_pic.png"), const Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "我的收藏", style: TextStyle(fontSize: 20), ), Text( "19首", style: TextStyle(fontSize: 16), ), ], ), const SizedBox( width: 80, ), Image.asset( "assets/img/user_next.png", ) ], ), ), const SizedBox( height: 10, ), //我的收藏和本地下载分界 InkWell( onTap: () async { final result = await Get.to(const MyDownloadView()); if (result == true) { setState(() { downloadCount = downloadManager.completedNumber(); }); } }, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Image.asset("assets/img/artist_pic.png"), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( "本地下载", style: TextStyle(fontSize: 20), ), Text( '${downloadCount}首', style: TextStyle(fontSize: 16), ), ], ), const SizedBox( width: 80, ), Image.asset( "assets/img/user_next.png", ) ], ), ), ], )), ///歌单 Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( '歌单 $playlistCount', style: const TextStyle( fontSize: 20, fontWeight: FontWeight.w500), ), Row( children: [ IconButton( onPressed: () { _showAddPlaylistDialog(); }, icon: Image.asset( "assets/img/user_add.png", width: 31, color: const Color(0xff404040), )), IconButton( onPressed: () {}, icon: Image.asset("assets/img/user_export.png", width: 31)) ], ) ], ), Container( padding: const EdgeInsets.only(left: 15, right: 15, top: 10, bottom: 5), child: ListView.builder( shrinkWrap: true, // 使得ListView适应内容高度 itemCount: playlistNames.length, // 根据歌单数量动态设置itemCount itemBuilder: (context, index) { return InkWell( onTap: () { print('点击成功'); Get.to(MyMusicView(songlistIdd: playlistid[index])); // 点击歌单时的回调,可以导航到歌单详情页 //待添加 }, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Image.asset("assets/img/artist_pic.png"), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( playlistNames[index], // 动态显示歌单名称 style: TextStyle(fontSize: 20), ), Text( '$playlistCount首', // 动态显示歌曲数量 style: TextStyle(fontSize: 16), ), ], ), const SizedBox(width: 80), Image.asset("assets/img/user_next.png"), ], ), ); }, ), ), InkWell( onTap: () { Get.to(const MyMusicView()); }, child: Column( children: List.generate(playlistNames.length, (index) { return Dismissible( key: Key(playlistNames[index]), direction: DismissDirection.endToStart, background: Container( color: Colors.red, alignment: Alignment.centerRight, padding: const EdgeInsets.only(right: 20.0), child: const Icon( Icons.delete, color: Colors.white, ), ), confirmDismiss: (direction) async { return await _showDeleteConfirmationDialog( context, index); }, onDismissed: (direction) { setState(() { playlistNames.removeAt(index); playlistid.removeAt(index); playlistCount--; }); }, child: ListTile( title: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Image.asset("assets/img/artist_pic.png"), const SizedBox( width: 30, ), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( playlistNames[index], style: const TextStyle(fontSize: 18), ), const Text( '0首', style: TextStyle(fontSize: 18), ), ], ), ], ), Image.asset( "assets/img/user_next.png", ) ], ), ), ); }), ), ), const SizedBox( height: 20, ), const Text( '已发布音乐10', style: TextStyle(fontSize: 20, fontWeight: FontWeight.w500), ), Container( padding: const EdgeInsets.only( left: 15, right: 20, top: 20, bottom: 10), child: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ InkWell( onTap: () { Get.to(const MyWorkView()); }, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Image.asset("assets/img/artist_pic.png"), const Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "我的作品", style: TextStyle(fontSize: 20), ), Text( "10首", style: TextStyle(fontSize: 16), ), ], ), const SizedBox( width: 80, ), Image.asset( "assets/img/user_next.png", ) ], ), ), ], )), ], ), ), ), ), ); } ///下弹框--退出,个人信息修改 Future _bottomSheet(BuildContext context) { return showModalBottomSheet( context: context, backgroundColor: Colors.white, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(30)), ), isScrollControlled: true, // 设置弹出框根据内容高度自适应 builder: (context) => Padding( padding: const EdgeInsets.only(top: 20), child: Column( mainAxisSize: MainAxisSize.min, // 使Column高度适应内容 crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Column( children: [ IconButton( onPressed: () async { Navigator.pop(context); bool result = await Get.to(const UserInfo()); if (result) { setState(() { avatar = AppData().currentAvatar; username = AppData().currentUsername; }); } }, icon: Image.asset("assets/img/user_infor.png"), iconSize: 60, ), const Text("账户信息") ], ), Column( children: [ IconButton( onPressed: () async { Navigator.pop(context); UniversalBean bean = await LogoutApiClient().logout( Authorization: AppData().currentToken, ); if (bean.code == 200) { Get.to(const BeginView()); } }, icon: Image.asset("assets/img/user_out.png"), iconSize: 60, ), const Text("退出登录") ], ), ], ), const SizedBox(height: 30), ], ), ), ); } ///弹出框--添加歌单 void _showAddPlaylistDialog() { _controller.clear(); showDialog( context: context, builder: (BuildContext context) { return AlertDialog( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), title: const Center( child: Text( "新建歌单", style: TextStyle(fontSize: 20), ), ), content: TextFieldColor(controller: _controller, hintText: '请输入歌单名称'), actions: [ TextButton( onPressed: () { Navigator.of(context).pop(); }, style: TextButton.styleFrom( backgroundColor: const Color(0xff429482), minimumSize: const Size(130, 50), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5.0), ), ), child: const Text( "取消", style: TextStyle(color: Colors.white), ), ), TextButton( onPressed: () async { Navigator.of(context).pop(); String enteredSongName = _controller.text; playlistCount++; // Add the new playlist setState(() { playlistNames.add(enteredSongName); }); SonglistBean bean = await SonglistApi().addSonglist( songlistName: _controller.text, Authorization: AppData().currentToken); }, style: TextButton.styleFrom( backgroundColor: const Color(0xff429482), minimumSize: const Size(130, 50), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5.0), ), ), child: const Text( "确认", style: TextStyle(color: Colors.white), ), ), ], ); }, ); } ///删除 Future _showDeleteConfirmationDialog( BuildContext context, int index) async { bool confirmDelete = await showDialog( context: context, builder: (BuildContext context) { return AlertDialog( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), title: Image.asset( "assets/img/warning.png", width: 47, height: 46, ), content: const Text( "确认删除?", textAlign: TextAlign.center, ), actions: [ TextButton( onPressed: () { Navigator.of(context).pop(false); }, style: TextButton.styleFrom( backgroundColor: const Color(0xff429482), minimumSize: const Size(130, 50), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5.0), ), ), child: const Text( "取消", style: TextStyle(color: Colors.white), ), ), TextButton( onPressed: () async { Navigator.of(context).pop(true); UniversalBean bean = await SonglistApi().delSonglist( Authorization: AppData().currentToken, id: playlistid[index], ); }, style: TextButton.styleFrom( backgroundColor: const Color(0xff429482), minimumSize: const Size(130, 50), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5.0), ), ), child: const Text( "确认", style: TextStyle(color: Colors.white), ), ), ], ); }, ); return confirmDelete == true; } }