如何传递数据到一个迷你播放器,并显示当前播放的歌曲在spotify克隆应用程序



基本上,我想在Gridtile被按下时显示一个迷你播放器,并且它的细节应该与被按下的tile相匹配。


class SongJBI extends StatefulWidget {
@override
State<SongJBI> createState() => SongJBIState();
}
class SongJBIState extends State<SongJBI> {

@override
final List<SongModel> sjmodel = [
SongModel(
id: 1,
name: 'rockstar(feat. 21 Savage)',
artist: 'Post Malone',
image: Image.asset('assets/rockstar.jpg'),
),
SongModel(
id: 2,
name: 'My Ordinary Life',
artist: 'The Living Tombstone',
image: Image.asset('assets/mol.jpg'),
),
SongModel(
id: 3,
name: 'House of Memories',
artist: 'Panic! At the Disco',
image: Image.asset('assets/ho.jpg'),
),
SongModel(
id: 4,
name: 'After Dark',
artist: 'Mr. Kitty',
image: Image.asset('assets/ad.jpg'),
),
];
Widget build(BuildContext context) {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: sjmodel.map((smo) {
final data = SongModel(
id: smo.id,
name: smo.name,
artist: smo.artist,
image: smo.image,
);
return GridTile(
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Song_Screen(recdata: data),
),
);
},
child: GestureDetector(
child: Container(
padding: EdgeInsets.all(10),
child: Column(
children: [
Container(
child: smo.image,
width: 150,
height: 150,
),
Container(
child: Text(
smo.name,
style: TextStyle(
color: Colors.white,
),
),
),
Container(
child: Text(
smo.artist,
style: TextStyle(
color: Colors.white,
),
),
),
],
),
),
),
));
}).toList()),
);
}
}

数据最初显示在歌曲屏幕上,但我希望迷你播放器根据点击改变它的数据,这样当歌曲屏幕最小化时,迷你播放器就会呈现出歌曲网格的细节。

这是歌曲屏幕的代码:

import 'package:flutter/material.dart';
import 'package:spotify_clone/Models/song_model.dart';
import 'package:spotify_clone/Widgets/song_recommend.dart';
class Song_Screen extends StatelessWidget {
final SongModel recdata;
Song_Screen({required this.recdata});
@override
double _sliderValue = 0;
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
centerTitle: true,
elevation: 0,
backgroundColor: Colors.transparent,
leading: IconButton(
splashRadius: 20,
icon: const Icon(
Icons.keyboard_arrow_down,
size: 35,
),
onPressed: () {
Navigator.of(context).pop();
},
),
actions: [
IconButton(
splashRadius: 20,
onPressed: () {},
icon: const Icon(
Icons.more_vert,
color: Colors.white,
),
)
],
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(
child: SizedBox(
width: 300,
height: 300,
child: recdata.image,
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
recdata.name,
style: TextStyle(
fontSize: 20,
color: Colors.white,
fontWeight: FontWeight.w600),
),
Text(
recdata.artist,
style: TextStyle(color: Colors.grey.shade400, fontSize: 16),
)
],
),
Column(
children: [
SliderTheme(
data: const SliderThemeData(
trackHeight: 2,
thumbShape:
RoundSliderThumbShape(enabledThumbRadius: 5),
overlayShape:
RoundSliderOverlayShape(overlayRadius: 0)),
child: Slider(
thumbColor: Colors.white,
inactiveColor: Colors.grey.shade700,
value: _sliderValue,
onChanged: ((value) {}),
activeColor: Colors.white,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'0:01',
style: TextStyle(
fontSize: 12, color: Colors.grey.shade300),
),
Text(
'3:00',
style: TextStyle(
fontSize: 12, color: Colors.grey.shade300),
)
],
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
IconButton(
padding: EdgeInsets.zero,
splashRadius: 20,
onPressed: () {},
icon: const Icon(
Icons.favorite_border,
color: Colors.white,
size: 30,
),
),
IconButton(
padding: EdgeInsets.zero,
splashRadius: 20,
onPressed: () {},
icon: const Icon(
Icons.fast_rewind,
color: Colors.white,
size: 30,
),
),
CircleAvatar(
radius: 25,
backgroundColor: Colors.white,
child: IconButton(
padding: EdgeInsets.zero,
splashRadius: 20,
onPressed: () {},
icon: const Icon(
Icons.play_arrow,
size: 35,
color: Colors.black,
),
),
),
IconButton(
padding: EdgeInsets.zero,
splashRadius: 20,
onPressed: () {},
icon: Icon(
Icons.fast_forward,
color: Colors.white,
size: 30,
),
),
IconButton(
padding: EdgeInsets.zero,
splashRadius: 20,
onPressed: () {},
icon: const Icon(
Icons.stop_circle,
color: Colors.white,
size: 30,
),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Spacer(),
IconButton(
padding: EdgeInsets.zero,
splashRadius: 20,
onPressed: () {},
icon: const Icon(Icons.share_outlined,
color: Colors.white)),
const SizedBox(
width: 10,
),
IconButton(
padding: EdgeInsets.zero,
splashRadius: 20,
onPressed: () {},
icon: const Icon(Icons.menu, color: Colors.grey))
],
)
],
),
),
),
);
}
}

这是迷你播放器的代码当歌曲被按下并且歌曲屏幕被最小化时它会弹出

import 'package:flutter/material.dart';
class Mini_Player extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
height: 70,
child: Card(
margin: EdgeInsets.all(5),
elevation: 10,
color: Colors.black54,
child: Row(
children: [
SizedBox(
width: 66,
height: 66,
child: Image.asset('assets/rockstar.jpg'),
),
SizedBox(
width: 10,
),
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
'Title',
style: TextStyle(
color: Colors.white,
),
),
Text(
'Artist',
style: TextStyle(
color: Colors.grey,
),
),
],
),
new Spacer(),
CircleAvatar(
radius: 25,
backgroundColor: Colors.black54,
child: IconButton(
padding: EdgeInsets.zero,
splashRadius: 20,
onPressed: () {},
icon: const Icon(
Icons.play_arrow,
size: 35,
color: Colors.white,
),
),
),
SizedBox(
width: 20,
)
],
)),
);
}
}

我对有状态的小部件和setstate真的很不好,所以请帮助我

这是呈现迷你播放器和歌曲等的主屏幕

class HomeScreen extends StatefulWidget {
HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [
Color.fromARGB(1, 158, 156, 156),
Colors.black,
],
)),
child: Column(
children: <Widget>[
SafeArea(
child: Row(
children: [
Text(
greeting(),
style: TextStyle(
color: Colors.white,
fontSize: 35,
),
textAlign: TextAlign.left,
),
new Spacer(),
IconButton(
icon: Icon(
Icons.settings,
color: Colors.white,
),
onPressed: () {},
),
IconButton(
icon: Icon(
Icons.search,
color: Colors.white,
),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => Search_Screen(),
),
);
},
),
],
),
),
Row(
children: [
Container(
child: Text(
'Recommended',
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
),
new Spacer(),
],
),
SongREC(),
Row(
children: [
Container(
child: Text(
'Jump back in',
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
),
new Spacer(),
],
),
SongJBI(),
new Spacer(),
Mini_Player(),
SizedBox(
height: 10,
)
],
),
),
bottomNavigationBar: BottomNavigationBar(
backgroundColor: Colors.transparent,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(
Icons.home,
color: Colors.white,
),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(
Icons.search,
color: Colors.white,
),
label: 'Search',
),
BottomNavigationBarItem(
icon: Icon(
Icons.library_add,
color: Colors.white,
),
label: 'My Library',
),
],
),
);
}
}

你应该看看MiniPlayer包

最新更新