You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PageView.builder切换页面后无法重载视频内容的问题求助

问题解决:PageView切换页面时加载对应YouTube视频

问题根源

你的所有PageView页面都复用同一个YoutubePlayerController,且仅在initState中初始化了第一个视频ID,后续切换页面时从未更新控制器的视频ID,导致始终播放同一视频。

修复方案

  1. 给PageController添加页面变化监听,实时获取当前页面索引
  2. 页面切换时,调用控制器的load()方法加载对应索引的YouTube视频ID
  3. 页面销毁时移除监听,避免内存泄漏

修改后的完整代码

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

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

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

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

class _WatchVideoLessonState extends State<WatchVideoLesson> {
  final List ytIDs = ['mluJOYd17L8', 'd-RCKfVjFI4', 'xXPuaB7UpB0'];
  // 可选:如果有视频标题可以对应存储
  final List videoTitles = ['视频1标题', '视频2标题', '视频3标题'];

  final _pageController = PageController();
  late YoutubePlayerController _controller;
  bool _isPlayerReady = false;
  int _currentIndex = 0; // 记录当前页面索引

  @override
  void dispose() {
    _pageController.removeListener(_onPageChanged); // 移除监听
    _controller.dispose();
    super.dispose();
  }

  @override
  void initState() {
    super.initState();
    _controller = YoutubePlayerController(
      initialVideoId: ytIDs.first,
      flags: const YoutubePlayerFlags(
        autoPlay: false,
      ),
    );
    _pageController.addListener(_onPageChanged); // 添加页面变化监听
  }

  // 页面变化回调
  void _onPageChanged() {
    final newIndex = _pageController.page?.round() ?? 0;
    if (newIndex != _currentIndex) {
      setState(() {
        _currentIndex = newIndex;
      });
      // 加载对应索引的视频
      _controller.load(ytIDs[_currentIndex]);
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        resizeToAvoidBottomInset: true,
        appBar: AppBar(
          title: const 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: _currentIndex > 0 ? () {
                                _pageController.previousPage(
                                  duration: const Duration(seconds: 1),
                                  curve: Curves.ease,
                                );
                              } : null, // 第一个页面禁用上一页按钮
                              child: const Icon(Icons.arrow_back_ios_new),
                            ),
                            const SizedBox(width: 10,),
                            Flexible(
                              child: Text(
                                videoTitles[index],
                                overflow: TextOverflow.ellipsis,
                              ),
                            ),
                            const SizedBox(width: 10,),
                            ElevatedButton(
                              style: ElevatedButton.styleFrom(
                                backgroundColor: Colors.green,
                              ),
                              onPressed: _currentIndex < ytIDs.length -1 ? () {
                                _pageController.nextPage(
                                  duration: const Duration(seconds: 1),
                                  curve: Curves.easeInOut,
                                );
                              } : null, // 最后一个页面禁用下一页按钮
                              child: const Icon(Icons.arrow_forward_ios),
                            ),
                          ],
                        ),
                      ),
                      const SizedBox(height: 20,),
                      YoutubePlayer(
                        progressColors: const ProgressBarColors(
                          playedColor: Colors.red,
                          handleColor: Colors.green,
                        ),
                        controller: _controller,
                        showVideoProgressIndicator: true,
                        onReady: (){
                          _isPlayerReady = true;
                        },
                      ),
                      const SizedBox(height: 10,),
                    ],
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

额外优化点

  • 添加了_currentIndex记录当前页面,用来禁用首尾页面的切换按钮,避免无效操作
  • 新增了视频标题列表,让每个页面显示对应视频的标题
  • 优化了按钮的可点击状态,提升用户体验

内容的提问来源于stack exchange,提问作者Tahir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 16:31:18