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.

219 lines
6.8 KiB

import 'package:flutter/material.dart';
import 'package:music_player_miao/view/rank_view.dart';
import 'package:music_player_miao/view/user/user_view.dart';
import '../home_view.dart';
import '../release_view.dart';
// 首先创建一个独立的迷你播放器组件
class MiniPlayer extends StatelessWidget {
const MiniPlayer({super.key});
@override
Widget build(BuildContext context) {
return Container(
height: 50, // 减小高度以适应底部
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 4,
offset: const Offset(0, -1),
),
],
),
child: Row(
children: [
// 歌曲封面
Container(
width: 50,
height: 50,
color: Colors.grey[200],
child: Image.asset(
'assets/img/artist_pic.png',
fit: BoxFit.cover,
),
),
// 歌曲信息
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'背对背拥抱',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 2),
Text(
'林俊杰',
style: TextStyle(
fontSize: 12,
color: Colors.grey[600],
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
),
// 播放控制
Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: const Icon(Icons.play_arrow),
onPressed: () {},
padding: EdgeInsets.zero,
constraints: const BoxConstraints(),
iconSize: 24,
),
const SizedBox(width: 16),
IconButton(
icon: const Icon(Icons.playlist_play),
onPressed: () {},
padding: EdgeInsets.zero,
constraints: const BoxConstraints(),
iconSize: 24,
),
const SizedBox(width: 8),
],
),
],
),
),
),
],
),
);
}
}
class MainTabView extends StatefulWidget {
const MainTabView({super.key});
@override
State<MainTabView> createState() => _MainTabViewState();
}
class _MainTabViewState extends State<MainTabView> with SingleTickerProviderStateMixin {
TabController? controller;
int selectTab = 0;
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
@override
void initState() {
super.initState();
controller = TabController(length: 4, vsync: this);
controller?.addListener(() {
selectTab = controller?.index ?? 0;
setState(() {});
});
}
@override
void dispose() {
super.dispose();
controller?.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
key: scaffoldKey,
body: Stack(
children: [
// TabBarView 占满整个屏幕
Column(
children: [
Expanded(
child: TabBarView(
controller: controller,
children: const [
HomeView(),
RankView(),
ReleaseView(),
UserView()
],
),
),
],
),
// 迷你播放器浮动在底部
Positioned(
left: 0,
right: 0,
bottom: 0,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const MiniPlayer(),
Container(
color: Colors.white,
child: TabBar(
controller: controller,
indicatorColor: Colors.transparent,
labelColor: Colors.black,
labelStyle: const TextStyle(fontSize: 12),
unselectedLabelColor: const Color(0xffCDCDCD),
unselectedLabelStyle: const TextStyle(fontSize: 12),
tabs: [
Tab(
height: 60,
icon: Image.asset(
selectTab == 0 ? "assets/img/home_tab.png" : "assets/img/home_tab_un.png",
width: 32,
height: 32,
),
text: "首页",
),
Tab(
height: 60,
icon: Image.asset(
selectTab == 1 ? "assets/img/list_tab.png" : "assets/img/list_tab_un.png",
width: 32,
height: 32,
),
text: "排行榜",
),
Tab(
height: 60,
icon: Image.asset(
selectTab == 2 ? "assets/img/music_tab.png" : "assets/img/music_tab_un.png",
width: 32,
height: 32,
),
text: "发布",
),
Tab(
height: 60,
icon: Image.asset(
selectTab == 3 ? "assets/img/user_tab.png" : "assets/img/user_tab_un.png",
width: 32,
height: 32,
),
text: "我的",
),
],
),
),
],
),
),
],
),
);
}
}