如何在Flutter中实现适配PageView.builder的视频播放列表
PageView.builder 视频播放列表实现方案
现有代码存在的问题
- 当前只初始化了单个
VideoPlayerController,绑定固定的assets/vod_1.mp4,无法适配多视频列表场景 - 翻页逻辑仅做了进度重置和播放,没有切换对应的视频资源,翻页后播放的还是原来的视频
- 缺少控制器的释放逻辑,容易出现内存泄漏
完整实现步骤
1. 定义基础变量
先声明视频资源列表、当前播放下标、控制器相关变量:
// 按实际需求替换为你的本地/网络视频地址列表 final List<String> videoList = [ 'assets/vod_1.mp4', 'assets/vod_2.mp4', 'assets/vod_3.mp4', ]; late int currentIndex; late VideoPlayerController _controller;
2. 重写初始化逻辑
封装通用的控制器初始化方法,修改原有的initState逻辑:
@override void initState() { super.initState(); currentIndex = 0; // 初始化首个视频的控制器 _initController(videoList[currentIndex]); } // 控制器初始化公共方法,后续翻页可复用 void _initController(String videoPath) { _controller = VideoPlayerController.asset(videoPath) ..initialize().then((value) { _controller.play(); _controller.setLooping(true); setState(() {}); }); }
3. 修改PageView.builder逻辑
补充itemCount配置,修改翻页逻辑实现视频切换,补全itemBuilder返回播放组件:
return PageView.builder( // 配置总页数为视频列表长度 itemCount: videoList.length, onPageChanged: (index) { if (index == currentIndex) return; // 先释放旧控制器避免内存泄漏 _controller.dispose(); // 更新当前播放下标 currentIndex = index; // 初始化新视频的控制器 _initController(videoList[currentIndex]); setState(() {}); }, itemBuilder: (context, index) { return _controller.value.isInitialized ? AspectRatio( aspectRatio: _controller.value.aspectRatio, child: VideoPlayer(_controller), ) : const Center(child: CircularProgressIndicator()); }, );
4. 补充页面销毁逻辑
页面退出时释放当前控制器,避免内存占用:
@override void dispose() { _controller.dispose(); super.dispose(); }
可选优化点
- 可添加预加载逻辑,提前初始化下一页的视频控制器,减少翻页后的加载等待时间
- 可加入滑动过程中暂停渲染的逻辑,降低滑动时的性能消耗
- 如果是百级以上的长视频列表,可设置最大缓存控制器数量,避免同时占用过多内存
内容的提问来源于stack exchange,提问作者tabsen700
相关产品推荐
相关产品推荐

