Skip to content

MediaQuery对组件的影响

当虚拟键盘唤起时,Flutter会自动调用build方法来重新构建UI,以适应键盘的变化。这是因为虚拟键盘的出现会改变屏幕的布局,需要更新UI以适应新的可见区域。 在键盘唤起时,MediaQuery.of(context)的结果可能会发生变化,因为键盘占用了一部分屏幕空间。这会触发build方法重新执行,并导致MediaQuery.of(context)被再次调用。 如果你的代码中直接依赖于MediaQuery.of(context)的结果,并且每次调用时都会触发build方法的重新执行,那么会导致频繁的重建和重新渲染。这可能会对性能产生一定的影响,尤其是在构建复杂UI时。 避免直接使用MediaQuery.of(context).size viewInsets padding viewPadding 为了避免频繁的重建,可以考虑在build方法中将MediaQuery.of(context)的结果缓存到局部变量中,并在需要使用时直接使用该变量。这样,即使触发了重建,只有在键盘状态发生改变的情况下会重新获取MediaQueryData对象。

dart
Widget build(BuildContext context) {
  final mediaQuery = MediaQuery.of(context);
  // 在需要使用屏幕信息时,直接使用缓存的变量 mediaQuery
  // ...
}

通过这种方式,可以减少不必要的MediaQuery.of(context)调用,从而降低因虚拟键盘导致的重复构建对性能的影响。在键盘出现和隐藏的过程中,屏幕的可见区域会发生改变,如果你想要根据键盘的状态进行相应的布局调整,还是需要重新构建来更新UI。因此,不必过分担心键盘导致的重建,它是为了确保UI与键盘状态一致而必要的反应。

Scaffold 之外使用 MediaQuery.of(context)要谨慎

通过 Scaffold 内的 context 获取到的 MediaQueryData 将因为 Scaffold 重构被影响

dart
Scaffold(
  resizeToAvoidBottomInset:true
)

如果为true,则[body]和脚手架的浮动小部件应自动调整大小,以避免因为环境MediaQueryMediaQueryData.viewInsets底部属性定义的屏幕键盘出现时的高度变化重构。
在使用MediaQuery.of(context)时,如果没有正确的上下文传递,可能会导致意想不到的结果。特别是在Scaffold之外使用MediaQuery.of(context)时,需要谨慎处理。
在Flutter中,MediaQuery.of(context)方法是通过上下文(BuildContext)来访问屏幕信息的。上下文是一个包含了当前小部件树位置和配置信息的对象。但是,上下文的范围是有限的,它只在小部件树中有效。当我们在Scaffold之外使用MediaQuery.of(context)时,可能会超出上下文的范围,导致无法获取正确的屏幕信息。
一个常见的示例是在应用程序的顶层MaterialApp小部件的构建方法中使用MediaQuery.of(context)。由于MaterialApp是整个应用程序的根小部件,它还没有建立与具体UI对象的关联,所以此时使用MediaQuery.of(context)将无法获取到正确的屏幕信息,可能会导致异常或错误的结果。
为了避免在Scaffold之外使用MediaQuery.of(context)时出现问题,可以考虑以下方法:

  1. 将需要访问屏幕信息的代码放在Scaffold内部,这样可以确保在正确的上下文范围内获取屏幕信息。
  2. 使用Builder小部件将代码包裹起来,以确保在正确的上下文范围内获取屏幕信息。Builder小部件会提供一个新的上下文,以便在内部使用MediaQuery.of(context)
dart
Widget build(BuildContext context) {
  return Scaffold(
    body: Builder(
      builder: (BuildContext context) {
        // 在Builder内部使用 MediaQuery.of(context)
        return Container(
          width: MediaQuery.of(context).size.width,
          height: MediaQuery.of(context).size.height,
          // ...
        );
      },
    ),
  );
}

替代

有时候,你需要使用MediaQuery.of(context)来获取屏幕信息,但是由于上下文范围问题,导致无法获取正确的屏幕信息。这时,你可以考虑使用其他方法来获取屏幕信息。 比如在组件中使用double.infinity来获取屏幕宽度,或者使用LayoutBuilder来获取屏幕信息。

仅用于培训和测试,通过使用本站代码内容随之而来的风险与本站无关。版权所有,未经授权请勿转载,保留一切权利。
ICP备案号:滇ICP备15009214号-13   公安网备:滇公网安备 53312302000061号