0

** Hello I am trying to build a quiz app and I want the quiz question and the options be shown after the video is ended completely.

I tried putting a condition for the text as

_videoPlayerController.value.position == _videoPlayerController.value.duration

Here there are 2 problems occurring, For some reason the text is not getting shown after the video is ended When I restart the app or go to the next question the text is getting shown at the start only before even the video starts playing.

Can anyone please help me with this, I'm really confused. **

class QuestionPage extends StatefulWidget {
  final Question question;
  // ignore: prefer_typing_uninitialized_variables
  const QuestionPage(
      {super.key,
      required this.question,
      required String videoPlayerController});

  @override
  State<QuestionPage> createState() => _QuestionPageState();
}

class _QuestionPageState extends State<QuestionPage> {
  late VideoPlayerController _videoPlayerController;
  ChewieController? chewieController;

  @override
  void initState() {
    super.initState();
    _initPlayer();
  }

  void _initPlayer() async {
    _videoPlayerController =
    VideoPlayerController.network(widget.question.video);
_videoPlayerController.initialize();
if (_videoPlayerController.value.position ==
    _videoPlayerController.value.duration) {
  print('Video Ended');
}
chewieController = ChewieController(
    aspectRatio: 16 / 9,
    zoomAndPan: true,
    videoPlayerController: _videoPlayerController,
    autoPlay: true,
    looping: false,
  );
}

@override
void dispose() {
   _videoPlayerController.dispose();
   chewieController?.dispose();
   super.dispose();
}

@override
Widget build(BuildContext context) {
   var state = Provider.of<QuizState>(context);

   return Column(
   mainAxisAlignment: MainAxisAlignment.end,
   children: [
     Expanded(
       child: Container(
         padding: const EdgeInsets.all(16),
         alignment: Alignment.center,
         child: Column(
           mainAxisAlignment: MainAxisAlignment.center,
           children: [
             Center(
                 child: SizedBox(
                    height: 200,
                    width: MediaQuery.of(context).size.width,
                    child: Chewie(
                      controller: chewieController!,
                    ),
             )),
             if (_videoPlayerController.value.position ==
                _videoPlayerController.value.duration)
              QuestionContainer(context),
          ],
        ),
      ),
    ),
    Container(
      padding: const EdgeInsets.all(20),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: widget.question.options.map((opt) {
          return Container(
            height: 90,
            margin: const EdgeInsets.only(bottom: 10),
            color: Colors.black26,
            child: InkWell(
              onTap: () {
                state.selected = opt;
                _bottomSheet(context, opt, state);
              },
              child: Container(
                padding: const EdgeInsets.all(16),
                child: Row(
                  children: [
                    Icon(
                        state.selected == opt
                            ? FontAwesomeIcons.circleCheck
                            : FontAwesomeIcons.circle,
                        size: 30),
                    Expanded(
                      child: Container(
                        margin: const EdgeInsets.only(left: 16),
                        child: Text(
                          opt.value,
                          style: Theme.of(context).textTheme.bodyMedium,
                        ),
                      ),
                    )
                  ],
                ),
              ),
            ),
          );
        }).toList(),
      ),
    )
   ],
 );
}

_bottomSheet(BuildContext context, Option opt, QuizState state) {
bool correctAnswer = opt.correct;

showModalBottomSheet(
  context: context,
  builder: (BuildContext context) {
    return Container(
      height: 250,
      padding: const EdgeInsets.all(16),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          Text(correctAnswer ? 'Good Job! Correct Answer' : 'Wrong Answer'),
          Text(
            opt.detail,
            style: const TextStyle(fontSize: 18, color: Colors.white54),
          ),
          ElevatedButton(
            style: ElevatedButton.styleFrom(
                backgroundColor: correctAnswer ? Colors.green : Colors.red),
            child: Text(
              correctAnswer ? 'Next' : 'Try Again',
              style: const TextStyle(
                color: Colors.white,
                letterSpacing: 1.5,
                fontWeight: FontWeight.bold,
              ),
            ),
            onPressed: () {
              if (correctAnswer) {
                state.nextPage();
              }
              Navigator.pop(context);
             },
           ),
         ],
       ),
     );
   },
 );
}

QuestionContainer(BuildContext context) {
    return Container(
     child: Text(widget.question.text),
    );
  }
}

Reposting this query, Please let me know if anyone can find a solution.

1 Answers1

0

I'm not 100% sure, but I think it's because you only check the video's position once, and nothing is causing the app to recheck the position once the video has completed. It looks like VideoPlayerController is a ChangeNotifier though, so you can build your widget to react to changes in the state of VideoPlayerController. One option is to use AnimatedBuilder. This answer has a good description of that and other ways to leverage a ChangeNotifier.

anqit
  • 780
  • 3
  • 12