我在下面创建了一个可重用微件,作为应用程序UI的一部分。可重用微件的代码如下
// ignore_for_file: prefer_typing_uninitialized_variables
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:musica/musica/domain/entities/riverpod_file.dart';
import 'package:musica/musica/presentation/manager/music_control_bloc.dart';
import 'package:musica/musica/presentation/widgets/constants.dart';
import 'package:musica/musica/presentation/widgets/reused_widgets/glassmorphism.dart';
import 'package:provider/provider.dart';
class GlassPlayerCard extends StatelessWidget {
final String currentPlayingMusicTitle;
final String musicArtist;
final String imageLink;
final MusicControlBloc? musicControlBloc;
GlassPlayerCard(
{required this.currentPlayingMusicTitle,
required this.musicArtist,
required this.imageLink,
this.musicControlBloc})
: super(key: UniqueKey());
@override
Widget build(BuildContext context) {
final musicBloc = BlocProvider.of<MusicControlBloc>(context);
final musicPlayerProvider = Provider.of<MusicPlayerProvider>(context);
return GlassMorphicContainer(
500.0,
100.0,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
addHorizontalSpacing(10),
Column(
children: [
addVerticalSpacing(15),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
border: Border.all(color: textColor, width: 2)),
height: 60,
width: 60,
child: Image.network(
imageLink,
),
),
),
],
),
addHorizontalSpacing(10),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
addVerticalSpacing(10),
Text(currentPlayingMusicTitle,
overflow: TextOverflow.ellipsis,
style: mediumWhiteTextStyle),
Text(musicArtist,
style:
smallWhiteTextStyle.copyWith(color: textColor)),
],
),
),
],
),
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
// GestureDetector(
// onTap: () {
// musicPlayerProvider.pauseMusic();
// },
// child: I
// con(Icons.pause, color: textColor)),
addHorizontalSpacing(10),
BlocBuilder<MusicControlBloc, MusicControlState>(
builder: (context, state) {
if (state is MusicControlInitialState) {
return GestureDetector(
onTap: () {
musicBloc.add(MusicControlPlayEvent());
},
child: Icon(Icons.play_arrow, color: textColor));
} else if (state is MusicControlLoadingState) {
return const Center(
child: CircularProgressIndicator(
color: kDefaultIconDarkColor,
value: 0.5,
strokeWidth: 2,
key: Key('musicLoading'),
),
);
} else if (state is MusicControlPlayingState) {
return GestureDetector(
onTap: () {
musicBloc.add(MusicControlPlayEvent());
},
child: Icon(Icons.pause, color: textColor));
} else {
return Container();
}
}),
addHorizontalSpacing(10),
Icon(Icons.skip_previous, color: textColor),
addHorizontalSpacing(20),
Icon(Icons.skip_next, color: textColor),
addHorizontalSpacing(50),
],
),
],
));
}
}
我用它在我的ui应用程序如下
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:musica/generated/assets.dart';
import 'package:musica/musica/domain/entities/riverpod_file.dart';
import 'package:musica/musica/presentation/manager/music_control_bloc.dart';
import 'package:musica/musica/presentation/widgets/constants.dart';
import 'package:musica/musica/presentation/widgets/reused_widgets/animated_like_button.dart';
import 'package:musica/musica/presentation/widgets/reused_widgets/custom_app_bar.dart';
import 'package:musica/musica/presentation/widgets/reused_widgets/glass_player_card.dart';
import 'package:musica/musica/presentation/widgets/reused_widgets/music_card_widget.dart';
import 'package:provider/provider.dart';
class CollectionDetailsWrapper extends StatelessWidget {
const CollectionDetailsWrapper({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => MusicControlBloc(),
);
}
}
class CollectionDetailsPage extends StatefulWidget {
final String imageUrl;
final String title;
final String artistName;
final int fans;
final String trackList;
const CollectionDetailsPage(
{Key? key,
required this.imageUrl,
required this.title,
required this.artistName,
required this.fans,
required this.trackList})
: super(key: key);
@override
State<CollectionDetailsPage> createState() => _CollectionDetailsPageState();
}
class _CollectionDetailsPageState extends State<CollectionDetailsPage> {
MusicPlayerProvider musicPlayerProvider = MusicPlayerProvider();
late Future trackListFuture;
final audioPlayer = AudioPlayer();
bool isPlaying = false;
Duration position = const Duration(seconds: 0);
Duration duration = const Duration(seconds: 0);
String currentPlayingMusicTitle = '';
String currentPlayingMusicArtist = '';
String currentTrackLink = '';
@override
void initState() {
super.initState();
trackListFuture = musicPlayerProvider.getTrackList(widget.trackList);
audioPlayer.onPlayerStateChanged.listen((event) {
setState(() {
isPlaying = event == PlayerState.playing;
});
});
audioPlayer.onDurationChanged.listen((newDuration) {
setState(() {
duration = newDuration;
});
});
audioPlayer.onPositionChanged.listen((newPosition) {
setState(() {
position = newPosition;
});
});
}
@override
Widget build(BuildContext context) {
final musicProvider =
Provider.of<MusicPlayerProvider>(context, listen: false);
final height = MediaQuery.of(context).size.height;
return Scaffold(
bottomNavigationBar: GlassPlayerCard(
imageLink: widget.imageUrl,
currentPlayingMusicTitle: currentPlayingMusicTitle,
musicArtist: currentPlayingMusicArtist,
),
extendBodyBehindAppBar: true,
extendBody: true,
appBar: const PreferredSize(
preferredSize: Size.fromHeight(50), child: CustomAppBar()),
body: Column(
children: [
Stack(clipBehavior: Clip.none, children: <Widget>[
Container(
decoration: BoxDecoration(
color: Colors.transparent,
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
widget.imageUrl,
),
),
),
height: height,
),
Container(
height: height,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
colors: [
backgroundColor,
Colors.transparent.withOpacity(0.5),
],
stops: const [0.5, 0.9],
)),
),
Positioned.fill(
child: ListView(
scrollDirection: Axis.vertical,
children: [
Column(
children: [
Container(
height: 234,
width: 360,
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: BorderRadius.circular(20),
image: DecorationImage(
image: NetworkImage(widget.imageUrl),
fit: BoxFit.cover,
),
),
),
Padding(
padding: const EdgeInsets.only(left: 20),
child: Text(
widget.title,
style: const TextStyle(
color: Color(0xffa4c7c6), fontSize: 25),
),
),
addVerticalSpacing(10),
Padding(
padding: const EdgeInsets.only(left: 20),
child: Text(
widget.artistName,
style: const TextStyle(
color: Color(0xffa4c7c6), fontSize: 15),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: Image.asset(
Assets.iconsPlayAllIcon,
height: 36,
)),
addHorizontalSpacing(5),
Expanded(
child: Image.asset(
Assets.iconsAddToCollecIcon,
height: 36,
)),
addHorizontalSpacing(5),
const Expanded(
child: AnimatedLikeButton(
text: "Like",
animationPath:
Assets.lottieAnimationsLike)),
],
),
),
],
),
SizedBox(
height: height - 510,
child: FutureBuilder(
future: trackListFuture,
initialData: const Center(
child: CircularProgressIndicator(
color: Colors.white,
backgroundColor: Colors.white,
)),
builder: (context, snapshot) {
if (snapshot.hasError) {
return const Center(
child: Text(
'Something went wrong',
style: mediumWhiteTextStyle,
));
}
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(
color: textColor,
),
);
}
return ListView.builder(
shrinkWrap: true,
physics: const ScrollPhysics(),
itemCount: musicPlayerProvider.musicList.length,
scrollDirection: Axis.vertical,
itemBuilder: (context, index) {
return MusicCardWidget(
name: musicPlayerProvider.musicList[index].name,
artist:
musicPlayerProvider.musicList[index].artist,
duration: musicPlayerProvider
.musicList[index].duration,
trackLink:
musicPlayerProvider.musicList[index].link,
onTapped: () {
musicProvider.playMusic(musicPlayerProvider
.musicList[index].link);
setState(() {
currentPlayingMusicArtist =
musicPlayerProvider
.musicList[index].artist;
currentPlayingMusicTitle =
musicPlayerProvider
.musicList[index].name;
currentTrackLink = musicPlayerProvider
.musicList[index].link;
});
},
);
},
);
}),
)
],
),
)
]),
],
),
);
}
}
现在的问题是我不断地得到上下文错误
The following assertion was thrown building GlassPlayerCard-[#fc2aa](dirty):
BlocProvider.of() called with a context that does not contain a MusicControlBloc.
No ancestor could be found starting from the context that was passed to BlocProvider.of<MusicControlBloc>().
This can happen if the context you used comes from a widget above the BlocProvider.
The context used was: GlassPlayerCard-[#fc2aa](dirty)
不管我把为应用程序的其余部分提供块的块提供程序放在哪里,甚至用块提供程序 Package 我的主MyApp函数也不起作用。
我试着将这个块作为构造函数添加到可重用的部件GlassPlayerCard中,但是没有解决这个问题。
这是我的主要. dart
import 'package:flutter/material.dart';
import 'package:musica/musica/domain/entities/riverpod_file.dart';
import 'package:musica/musica/presentation/pages/screens/home.dart';
import 'package:provider/provider.dart';
void main() {
runApp(MultiProvider(
builder: (context, _) {
return const MyApp();
},
providers: [
ChangeNotifierProvider(create: (context) => MusicPlayerProvider()),
],
));
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: Home(),
);
}
}
1条答案
按热度按时间fjaof16o1#
在代码中没有任何地方实际将块传递给
GlassPlayerCard
,原因是您创建了一个包含BlocProvider
的CollectionDetailsWrapper
,但实际上并没有在任何地方使用它(至少从所显示的代码片段来看)。确保你用你的
CollectionDetailsWrapper
Package 你的CollectionDetailsPage
,这样就可以了。