使用flick_video_player旋转设备后返回页面出现黑屏问题求助
问题描述
使用flick_video_player包播放视频时,视频播放正常,但旋转设备(向左/向右)后返回上一页会出现黑屏;不旋转设备则一切正常。
原代码
import 'package:flick_video_player/flick_video_player.dart'; import 'package:flutter/material.dart'; import 'package:video_player/video_player.dart'; import 'package:visibility_detector/visibility_detector.dart'; class PlayVideo extends StatefulWidget { const PlayVideo({super.key, required this.videoURL}); final String videoURL; @override State<PlayVideo> createState() => _PlayVideoState(); } class _PlayVideoState extends State<PlayVideo> { late FlickManager flickManager; @override void initState() { super.initState(); flickManager = FlickManager( videoPlayerController: VideoPlayerController.networkUrl( Uri.parse(widget.videoURL), ), ); } @override void dispose() { flickManager.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: VisibilityDetector( key: ObjectKey(flickManager), onVisibilityChanged: (visibility) { if (visibility.visibleFraction == 0 && mounted) { flickManager.flickControlManager?.autoPause(); } else if (visibility.visibleFraction == 1) { flickManager.flickControlManager?.autoResume(); } }, child: Center( child: AspectRatio( aspectRatio: 16 / 10, child: FlickVideoPlayer( flickManager: flickManager, ), ), ), ), ); } }
解决方案
黑屏问题核心是设备旋转时Flutter会重建页面State,导致视频资源管理异常,返回上一页时未正确清理状态。可通过以下修改解决:
关键修改点
- 用
AutomaticKeepAliveClientMixin保持页面状态,避免旋转时重复初始化资源 - 用
WillPopScope监听返回事件,主动清理视频资源 - 增强状态判断,避免销毁后调用控制器方法
修改后的代码
import 'package:flick_video_player/flick_video_player.dart'; import 'package:flutter/material.dart'; import 'package:video_player/video_player.dart'; import 'package:visibility_detector/visibility_detector.dart'; class PlayVideo extends StatefulWidget { const PlayVideo({super.key, required this.videoURL}); final String videoURL; @override State<PlayVideo> createState() => _PlayVideoState(); } class _PlayVideoState extends State<PlayVideo> with AutomaticKeepAliveClientMixin { late FlickManager flickManager; @override bool get wantKeepAlive => true; @override void initState() { super.initState(); _initFlickManager(); } void _initFlickManager() { flickManager = FlickManager( videoPlayerController: VideoPlayerController.networkUrl( Uri.parse(widget.videoURL), ), ); } @override void didUpdateWidget(covariant PlayVideo oldWidget) { super.didUpdateWidget(oldWidget); // 视频URL变化时重新初始化资源 if (oldWidget.videoURL != widget.videoURL) { flickManager.dispose(); _initFlickManager(); } } @override void dispose() { flickManager.dispose(); super.dispose(); } @override Widget build(BuildContext context) { super.build(context); // 必须调用以维持状态 return WillPopScope( onWillPop: () async { // 返回前主动暂停并释放资源 flickManager.flickControlManager?.pause(); flickManager.dispose(); return true; }, child: Scaffold( body: VisibilityDetector( key: ObjectKey(flickManager), onVisibilityChanged: (visibility) { if (visibility.visibleFraction == 0 && mounted) { flickManager.flickControlManager?.autoPause(); } else if (visibility.visibleFraction == 1 && mounted) { flickManager.flickControlManager?.autoResume(); } }, child: Center( child: AspectRatio( aspectRatio: 16 / 10, child: FlickVideoPlayer( flickManager: flickManager, ), ), ), ), ), ); } }
内容的提问来源于stack exchange,提问作者Ahmed Alsaba
相关产品推荐
相关产品推荐

