Flutter中如何在initState内获取设备宽高并传递到其他页面?
问题原因
你当前的实现存在问题,报错的核心原因是initState执行阶段,State关联的BuildContext还未完全挂载到Widget树,无法直接用来获取MediaQuery这类依赖Widget树的共享数据。
修复方案
两种常用的修复方案,按需选择即可:
- 方案1:使用
addPostFrameCallback回调,在首帧渲染完成后执行逻辑
等待Widget挂载完成后再调用context获取数据,符合原生生命周期规范:
class _SplashPageState extends State<SplashPage> { @override void initState(){ super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { var deviceHeight = MediaQuery.of(context).size.height; var deviceWidth = MediaQuery.of(context).size.width; Future.delayed(const Duration(seconds: 1), () async { // 通过arguments参数传递宽高到目标页面 await Navigator.pushNamed(context, "/home", arguments: { "deviceWidth": deviceWidth, "deviceHeight": deviceHeight }); }); }); } }
目标页面通过ModalRoute.of(context)?.settings.arguments即可拿到传递的宽高参数。
- 方案2:直接通过平台调度器获取屏幕参数,不需要依赖context
无需等待context就绪,initState阶段可直接调用,更适合闪屏页的场景:
class _SplashPageState extends State<SplashPage> { @override void initState(){ super.initState(); // 直接获取屏幕物理尺寸转换为逻辑宽高,不依赖Widget树 final view = WidgetsBinding.instance.platformDispatcher.views.first; final deviceHeight = view.physicalSize.height / view.devicePixelRatio; final deviceWidth = view.physicalSize.width / view.devicePixelRatio; Future.delayed(const Duration(seconds: 1), () async { await Navigator.pushNamed(context, "/home", arguments: { "deviceWidth": deviceWidth, "deviceHeight": deviceHeight }); }); } }
普通单窗口App可直接使用该方案,多窗口适配场景需要根据当前窗口调整取view的逻辑。
内容的提问来源于stack exchange,提问作者Superjay
相关产品推荐
相关产品推荐

