dart 我如何使我的区块工作在一个可重用的小部件创建?

sulc1iza  于 2023-02-27  发布在  其他
关注(0)|答案(1)|浏览(103)

我在下面创建了一个可重用微件,作为应用程序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(),
    );
  }
}
fjaof16o

fjaof16o1#

在代码中没有任何地方实际将块传递给GlassPlayerCard,原因是您创建了一个包含BlocProviderCollectionDetailsWrapper,但实际上并没有在任何地方使用它(至少从所显示的代码片段来看)。
确保你用你的CollectionDetailsWrapper Package 你的CollectionDetailsPage,这样就可以了。

// Your new wrapper definition
class CollectionDetailsWrapper extends StatelessWidget {

 final Widget child;

 const CollectionDetailsWrapper({Key? key, required this.child}) : super(key: key);

 @override
 Widget build(BuildContext context) {
   return BlocProvider(
     create: (context) => MusicControlBloc(),
     child: child,
   );
 }
}

/// your new implementation wherever you are declaring your details page

...
CollectionDetailsWrapper(
   child: CollectionDetailsPage(...),
),
...

相关问题