import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../controllers/qqmusic_controller.dart'; import '../models/song_model.dart'; class QQMusicView extends GetView { const QQMusicView({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('QQ音乐'), actions: [ Obx(() => controller.isLoggedIn.value ? IconButton( icon: const Icon(Icons.logout), onPressed: controller.logout, ) : IconButton( icon: const Icon(Icons.login), onPressed: controller.login, )), ], ), body: Obx(() { if (!controller.isLoggedIn.value) { return _buildLoginView(); } return _buildMainView(); }), bottomNavigationBar: Obx(() { if (controller.currentSong.value != null) { return _buildMiniPlayer(); } return const SizedBox.shrink(); }), ); } Widget _buildLoginView() { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon( Icons.music_note, size: 100, color: Colors.blue, ), const SizedBox(height: 20), const Text( '请先登录QQ音乐', style: TextStyle(fontSize: 18), ), const SizedBox(height: 20), ElevatedButton( onPressed: controller.login, child: const Text('登录QQ音乐'), ), ], ), ); } Widget _buildMainView() { return Column( children: [ _buildSearchBar(), Expanded( child: Obx(() { if (controller.isSearching.value) { return const Center(child: CircularProgressIndicator()); } if (controller.searchResults.isEmpty) { return const Center( child: Text('搜索歌曲开始您的音乐之旅'), ); } return _buildSearchResults(); }), ), ], ); } Widget _buildSearchBar() { return Container( padding: const EdgeInsets.all(16), child: TextField( decoration: const InputDecoration( hintText: '搜索歌曲、歌手、专辑', prefixIcon: Icon(Icons.search), border: OutlineInputBorder(), ), onSubmitted: controller.searchSongs, ), ); } Widget _buildSearchResults() { return ListView.builder( itemCount: controller.searchResults.length, itemBuilder: (context, index) { final song = controller.searchResults[index]; return _buildSongItem(song); }, ); } Widget _buildSongItem(SongModel song) { return ListTile( leading: Container( width: 50, height: 50, decoration: BoxDecoration( color: Colors.grey[300], borderRadius: BorderRadius.circular(8), ), child: song.albumPic != null ? ClipRRect( borderRadius: BorderRadius.circular(8), child: Image.network( song.albumPic!, fit: BoxFit.cover, errorBuilder: (context, error, stackTrace) { return const Icon(Icons.music_note); }, ), ) : const Icon(Icons.music_note), ), title: Text( song.name, maxLines: 1, overflow: TextOverflow.ellipsis, ), subtitle: Text( '${song.artist} • ${song.album}', maxLines: 1, overflow: TextOverflow.ellipsis, ), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ Text(song.durationText), const SizedBox(width: 8), IconButton( icon: const Icon(Icons.play_arrow), onPressed: () => controller.playSong( song, songList: controller.searchResults, ), ), ], ), ); } Widget _buildMiniPlayer() { return Obx(() { final song = controller.currentSong.value!; return Container( height: 80, decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 4, offset: const Offset(0, -2), ), ], ), child: Column( children: [ // 进度条 Obx(() => LinearProgressIndicator( value: controller.totalDuration.value > 0 ? controller.currentPosition.value / controller.totalDuration.value : 0, backgroundColor: Colors.grey[300], valueColor: const AlwaysStoppedAnimation(Colors.blue), )), Expanded( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Row( children: [ // 歌曲信息 Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( song.name, maxLines: 1, overflow: TextOverflow.ellipsis, style: const TextStyle(fontWeight: FontWeight.bold), ), Text( song.artist, maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle(color: Colors.grey[600]), ), ], ), ), // 控制按钮 Row( children: [ IconButton( icon: const Icon(Icons.skip_previous), onPressed: controller.previousSong, ), Obx(() => IconButton( icon: Icon( controller.isPlaying.value ? Icons.pause : Icons.play_arrow, ), onPressed: controller.togglePlayPause, )), IconButton( icon: const Icon(Icons.skip_next), onPressed: controller.nextSong, ), ], ), ], ), ), ), ], ), ); }); } }