Flutter Chewie播放器控件无法点击、进度条无法seek跳转问题
Chewie播放器控制栏无响应、进度条无法拖动问题
问题现象
修改Chewie播放器官方示例代码调试时,播放器控制组件无法响应点击操作,进度条也无法拖动执行seek跳转。
依赖版本
video_player: ^2.4.5chewie: ^1.3.4
复现效果

复现代码
import 'package:chewie/chewie.dart'; import 'package:flutter/material.dart'; import 'package:video_player/video_player.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; class VideoView extends StatefulWidget { const VideoView({ Key? key, }) : super(key: key); @override State<StatefulWidget> createState() { return _VideoViewState(); } } class _VideoViewState extends State<VideoView> { late VideoPlayerController _videoPlayerController; ChewieController? _chewieController; int? bufferDelay; @override void initState() { super.initState(); initializePlayer(); } @override void dispose() { _videoPlayerController.dispose(); _chewieController?.dispose(); super.dispose(); } List<String> srcs = [ "https://assets.mixkit.co/videos/preview/mixkit-spinning-around-the-earth-29351-large.mp4", "https://assets.mixkit.co/videos/preview/mixkit-daytime-city-traffic-aerial-view-56-large.mp4", "https://assets.mixkit.co/videos/preview/mixkit-a-girl-blowing-a-bubble-gum-at-an-amusement-park-1226-large.mp4" ]; Future<void> initializePlayer() async { _videoPlayerController = VideoPlayerController.network(srcs[currPlayIndex]); await Future.wait([ _videoPlayerController.initialize(), ]); _createChewieController(); setState(() {}); } void _createChewieController() { _chewieController = ChewieController( videoPlayerController: _videoPlayerController, autoPlay: true, looping: true, progressIndicatorDelay: Duration(seconds: 1), additionalOptions: (context) { return <OptionItem>[ OptionItem( onTap: toggleVideo, iconData: Icons.live_tv_sharp, title: 'Toggle Video Src', ), ]; }, customControls: MaterialControls( showPlayButton: true, ), hideControlsTimer: const Duration(seconds: 3), ); } int currPlayIndex = 0; Future<void> toggleVideo() async { await _videoPlayerController.pause(); currPlayIndex += 1; if (currPlayIndex >= srcs.length) { currPlayIndex = 0; } await initializePlayer(); } @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData( brightness: Brightness.light, colorScheme: const ColorScheme.light(secondary: Colors.red), disabledColor: Colors.grey.shade400, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: Scaffold( backgroundColor: Colors.white, appBar: AppBar( backgroundColor: Colors.white, leading: IconButton( splashRadius: 10.sp, icon: Container( height: kToolbarHeight, width: kToolbarHeight, decoration: BoxDecoration( color: Colors.transparent, borderRadius: BorderRadius.circular(100) ), child: Icon(Icons.arrow_back_rounded, color: Colors.white, size: 22.sp) ), onPressed: (){ Navigator.pop(context); }, ), ), extendBody: true, extendBodyBehindAppBar: true, body: Column( children: <Widget>[ Expanded( child: Center( child: _chewieController != null && _chewieController!.videoPlayerController.value.isInitialized ? Chewie( controller: _chewieController!, ) : Column( mainAxisAlignment: MainAxisAlignment.center, children: const [ CircularProgressIndicator(), SizedBox(height: 20), Text('Loading'), ], ), ), ), SizedBox(height: 100.sp,) ], ), ), ); } }
问题原因
问题由三处错误写法共同导致:
- 组件内重复嵌套
MaterialApp。Flutter全局只需要在应用根节点放置一个MaterialApp,子组件中重复嵌套会导致子树拿到的MediaQuery坐标数据、手势上下文和根视图不一致,控制栏按钮、进度条的手势命中区域和实际渲染位置错位,所有点击、拖动事件无法正确命中对应控件。 flutter_screenutil未正确初始化。代码中直接在子组件内使用sp单位做尺寸计算,但ScreenUtil的适配初始化必须拿到顶层MaterialApp的上下文才能生效,未初始化时的尺寸计算错误会进一步放大小部件的位置偏移,加剧手势失效问题。- 多余的
Center嵌套。Chewie组件本身会自动适配父容器尺寸计算宽高比,在外层额外套Center会干扰控件的位置和手势区域计算。
修复方案
- 移除
VideoView的build方法中嵌套的MaterialApp和顶层Scaffold结构,页面级的脚手架、主题配置统一放在应用根节点维护,不要在单个业务组件中重复声明。 - 在应用根节点完成
flutter_screenutil初始化,参考写法:
void main() { runApp( ScreenUtilInit( designSize: const Size(360, 690), // 替换为项目实际设计稿尺寸 builder: (context, child) => const MyApp(), // MyApp为应用根MaterialApp ) ); }
- 去掉Chewie组件外层包裹的
Center组件,让Chewie直接填充Expanded分配的空间即可。
修复后控制栏点击、进度条拖动功能即可恢复正常。
内容的提问来源于stack exchange,提问作者FeelRightz
相关产品推荐
相关产品推荐

