Flutter实现视频结束后显示问答组件的问题求助
解决Quiz App视频播放完再显示题目的问题
问题根源
- 精度匹配问题:视频播放结束时,
_videoPlayerController.value.position和_videoPlayerController.value.duration几乎不会完全相等(比如视频时长10.000秒,position可能停在9.999秒就触发结束),直接判断相等会导致条件不触发。 - 初始状态误判:应用启动或切换题目时,视频控制器的
position和duration初始都是Duration.zero,此时相等条件成立,导致题目提前显示。
解决方案
用独立状态变量控制题目显示,配合视频播放状态监听,同时加入精度容错:
- 定义
_showQuiz布尔变量,初始设为false,专门控制题目是否显示。 - 给视频控制器添加监听,判断播放进度是否接近结束(留100毫秒容错空间),满足条件时将
_showQuiz设为true。 - 切换题目或重启时,重置
_showQuiz并重新初始化视频控制器。
修改后的代码示例
import 'package:flutter/material.dart'; import 'package:video_player/video_player.dart'; class QuizVideoScreen extends StatefulWidget { const QuizVideoScreen({super.key}); @override State<QuizVideoScreen> createState() => _QuizVideoScreenState(); } class _QuizVideoScreenState extends State<QuizVideoScreen> { bool _showQuiz = false; late VideoPlayerController _videoPlayerController; @override void initState() { super.initState(); _initVideoController(); } // 初始化视频控制器 void _initVideoController() { _showQuiz = false; // 重置题目显示状态 _videoPlayerController = VideoPlayerController.network( 'https://example.com/your-video.mp4', // 替换为你的视频地址 )..initialize().then((_) { setState(() {}); _videoPlayerController.play(); // 添加播放状态监听 _videoPlayerController.addListener(_checkVideoEnd); }); } // 检查视频是否播放结束 void _checkVideoEnd() { final position = _videoPlayerController.value.position; final duration = _videoPlayerController.value.duration; // 视频已初始化,且进度接近结束(留100毫秒容错) if (duration != Duration.zero && position >= duration - const Duration(milliseconds: 100)) { setState(() { _showQuiz = true; }); // 移除监听避免重复触发 _videoPlayerController.removeListener(_checkVideoEnd); } } @override Widget build(BuildContext context) { return Scaffold( body: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // 视频播放区域 if (_videoPlayerController.value.isInitialized) AspectRatio( aspectRatio: _videoPlayerController.value.aspectRatio, child: VideoPlayer(_videoPlayerController), ), // 测验题目区域(仅当_showQuiz为true时显示) if (_showQuiz) Expanded( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Text( '这是测验题目?', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), ), const SizedBox(height: 20), ElevatedButton(onPressed: () {}, child: const Text('选项A')), ElevatedButton(onPressed: () {}, child: const Text('选项B')), ElevatedButton(onPressed: () {}, child: const Text('选项C')), ], ), ), ), // 切换题目按钮 Padding( padding: const EdgeInsets.all(16.0), child: ElevatedButton( onPressed: () { // 释放旧控制器,重新初始化 _videoPlayerController.dispose(); _initVideoController(); }, child: const Text('切换到下一题'), ), ), ], ), ); } @override void dispose() { _videoPlayerController.dispose(); super.dispose(); } }
关键优化点
- 用
_showQuiz独立控制显示,彻底避免初始状态的误判。 - 采用
position >= duration - 100ms的判断逻辑,解决精度匹配问题。 - 视频结束后移除监听,防止后续状态变化重复触发。
- 切换题目时重置状态并重新初始化控制器,确保新视频播放前题目不显示。
内容的提问来源于stack exchange,提问作者Sultanshah Rajguru
相关产品推荐
相关产品推荐

