使用PageView.builder切换页面后无法重载视频内容的问题求助
问题解决:PageView切换页面时加载对应YouTube视频
问题根源
你的所有PageView页面都复用同一个YoutubePlayerController,且仅在initState中初始化了第一个视频ID,后续切换页面时从未更新控制器的视频ID,导致始终播放同一视频。
修复方案
- 给
PageController添加页面变化监听,实时获取当前页面索引 - 页面切换时,调用控制器的
load()方法加载对应索引的YouTube视频ID - 页面销毁时移除监听,避免内存泄漏
修改后的完整代码
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
相关产品推荐
相关产品推荐

