Tahir
Tahir

Reputation: 300

PageView.builder reload content after navigation to the new page

I have a list of videos urls/youtube IDs and a PageView.builder. I want to load next/previous video according to position in the list. For example:

List videos = ['vid_0', 'vid_1', 'vid_2', 'vid_3', 'vid_4'] if current Playing video is vid_2, it should reload the next video or previous video of the list based on button event.

Currently when I press next or previous button, the same video is loaded but the PageView makes pages equal to the length of list. I am using youtube_video_player package.

Here is my code:

import 'package:flutter/material.dart';
import 'package:youtube_player_flutter/youtube_player_flutter.dart';

void main(){
  runApp(WatchVideoLesson());
}

class WatchVideoLesson extends StatefulWidget {
  const WatchVideoLesson({Key? key}) : super(key: key);

  @override
  State<WatchVideoLesson> createState() => _WatchVideoLessonState();
}

class _WatchVideoLessonState extends State<WatchVideoLesson> {

  List ytIDs = ['mluJOYd17L8', 'd-RCKfVjFI4', 'xXPuaB7UpB0'];
  var playingVideo;

  final _pageController = PageController();
  late YoutubePlayerController _controller;
  bool _isPlayerReady = false;


  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  void initState() {
    _controller = YoutubePlayerController(
        initialVideoId: ytIDs.first,
        flags: const YoutubePlayerFlags(
          autoPlay: false,
        )
    );
    // TODO: implement initState
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        resizeToAvoidBottomInset: true,
        appBar: AppBar(
          title: Text('Week'),
          backgroundColor: Colors.red,
        ),
        body:
        Column(
            children:[
              Expanded(
                child: PageView.builder(
                    physics: const NeverScrollableScrollPhysics(),
                    controller: _pageController,
                    itemCount: ytIDs.length,
                    itemBuilder: (context, index) {
                      return Column(
                        children: [
                          Container(
                            decoration: const BoxDecoration(
                              color: Colors.grey,
                            ),
                            child: Row(
                              mainAxisAlignment: MainAxisAlignment.spaceAround,
                              children: [
                                ElevatedButton(style: ElevatedButton.styleFrom(
                                    backgroundColor: Colors.red),
                                    onPressed: () {
                                      _pageController.previousPage(duration: Duration(seconds: 1), curve: Curves.ease);
                                    },
                                    child: Icon(Icons.arrow_back_ios_new,)),
                                SizedBox(width: 10,),
                                Flexible(child: Text('Video Title', overflow: TextOverflow.ellipsis,)),
                                SizedBox(width: 10,),
                                ElevatedButton(style: ElevatedButton.styleFrom(
                                    backgroundColor: Colors.green),
                                    onPressed: () {
                                      _pageController.nextPage(duration: Duration(seconds: 1), curve: Curves.easeInOut);

                                    },
                                    child: Icon(Icons.arrow_forward_ios,)),
                              ],
                            ),
                          ),
                          SizedBox(height: 20,),
                          YoutubePlayer(
                            progressColors: const ProgressBarColors(
                                playedColor: Colors.red,
                                handleColor: Colors.green),
                            controller: _controller,
                            showVideoProgressIndicator: true,
                            onReady: (){
                              _isPlayerReady = true;
                            },
                          ),

                          SizedBox(height: 10,),
                        ],
                      );
                    }
                ),
              ),
            ]
        ),
      ),
    );
  }
}

Upvotes: 0

Views: 792

Answers (1)

Md. Yeasin Sheikh
Md. Yeasin Sheikh

Reputation: 63649

Current snippet using the same controller on YoutubePlayer and my guess this is issue having same video. I separating the widget so that it can have different controller for PageView item.

class WatchVideoLesson extends StatefulWidget {
  const WatchVideoLesson({Key? key}) : super(key: key);

  @override
  State<WatchVideoLesson> createState() => _WatchVideoLessonState();
}

class _WatchVideoLessonState extends State<WatchVideoLesson> {
  List ytIDs = ['mluJOYd17L8', 'd-RCKfVjFI4', 'xXPuaB7UpB0'];
  var playingVideo;

  final _pageController = PageController();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Column(children: [
          Expanded(
            child: PageView.builder(
                physics: const NeverScrollableScrollPhysics(),
                controller: _pageController,
                itemCount: ytIDs.length,
                itemBuilder: (context, index) {
                  return Column(
                    children: [
                      Container(
                        decoration: const BoxDecoration(
                          color: Colors.grey,
                        ),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.spaceAround,
                          children: [
                            ElevatedButton(
                                style: ElevatedButton.styleFrom(
                                    backgroundColor: Colors.red),
                                onPressed: () {
                                  _pageController.previousPage(
                                      duration: Duration(seconds: 1),
                                      curve: Curves.ease);
                                },
                                child: Icon(
                                  Icons.arrow_back_ios_new,
                                )),
                            SizedBox(
                              width: 10,
                            ),
                            Flexible(
                                child: Text(
                              'Video Title',
                              overflow: TextOverflow.ellipsis,
                            )),
                            SizedBox(
                              width: 10,
                            ),
                            ElevatedButton(
                                style: ElevatedButton.styleFrom(
                                    backgroundColor: Colors.green),
                                onPressed: () {
                                  _pageController.nextPage(
                                      duration: Duration(seconds: 1),
                                      curve: Curves.easeInOut);
                                },
                                child: Icon(
                                  Icons.arrow_forward_ios,
                                )),
                          ],
                        ),
                      ),
                      YTPlayer(ytIDs: ytIDs[index]),
                      SizedBox(
                        height: 20,
                      ),
                      SizedBox(
                        height: 10,
                      ),
                    ],
                  );
                }),
          ),
        ]),
      ),
    );
  }
}

class YTPlayer extends StatefulWidget {
  final String ytIDs;
  const YTPlayer({super.key, required this.ytIDs});

  @override
  State<YTPlayer> createState() => _YTPlayerState();
}

class _YTPlayerState extends State<YTPlayer> {
  late YoutubePlayerController _controller;
  bool _isPlayerReady = false;

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  void initState() {
    super.initState();
    _controller = YoutubePlayerController(
        initialVideoId: widget.ytIDs,
        flags: const YoutubePlayerFlags(
          autoPlay: false,
        ));
  }

  @override
  Widget build(BuildContext context) {
    return YoutubePlayer(
      controller: _controller,
      progressColors: const ProgressBarColors(
          playedColor: Colors.red, handleColor: Colors.green),
      showVideoProgressIndicator: true,
      onReady: () {
        _isPlayerReady = true;
      },
    );
  }
}

Upvotes: 1

Related Questions