Flutter中Navigator.push跳转后如何复用父页Widget避免重新构建
可行解决方案
- 抽离视频控制器到外部持有
不要将VideoPlayerController的初始化逻辑放在视频组件的initState中,改为由父组件或全局状态管理(如Provider、GetX等)持有控制器实例,再将控制器传递给视频组件使用。即使focused_menu跳转后重新构建视频组件,只要引用的是同一个控制器实例,就不会触发重新初始化,原有播放状态、加载进度都会保留。
示例代码:
// 父组件中提前初始化并持有控制器 late VideoPlayerController _controller; @override void initState() { super.initState(); _controller = VideoPlayerController.network( 'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4' )..initialize().then((_) => setState(() {})); } // 构建子视频组件时直接传入控制器,子组件仅负责渲染无需处理初始化逻辑 VideoPlayerWidget(controller: _controller)
替换长按菜单实现方案
focused_menu的核心问题是通过Navigator.push新页面承载菜单和原组件,你可以直接修改插件源码,将路由跳转逻辑改为基于Overlay悬浮层实现,全程不触发页面切换,原组件不会被卸载重建,自然不会触发视频重载。如果不想自行修改源码,也可以替换为其他基于Overlay实现的同类型长按菜单插件。为视频组件添加GlobalKey
给自定义视频组件设置GlobalKey,Flutter在Widget树结构发生变化时,会根据Key复用对应的State实例,也就保留了原有的控制器,不会重新执行initState逻辑。需要注意GlobalKey不要重复声明,使用完成后及时释放控制器避免内存泄漏。
内容的提问来源于stack exchange,提问作者w84m8
相关产品推荐
相关产品推荐

