• 第四百四十四回



    我们在上一章回中介绍了"如何获取AppBar的高度"相关的内容,本章回中将介绍关于MediaQuery的优化.闲话休提,让我们一起Talk Flutter吧。

    在这里插入图片描述

    1. 问题描述

    我们在前面章回中介绍获取屏幕参数时使用过MediaQuery类,主要通过它来获取MediaQueryData对象,然后从MediaQueryData对象中获取屏幕相关的参数。比如
    常用的屏幕长宽和宽度,不过在使用时如果遇到键盘弹出或者隐藏时会引起Scaffold进行重绘(rebuild),而且是多次重绘,这种重绘显然不合理,它会导致不必要的
    性能开销,本章回中将介绍如何优化这种不合理的重绘。

    2. 优化方法

    明白我们遇到的问题后,我们介绍如何去解决这个问题,我们提供了两种解决方法,在接下来的小节中将介绍这两种方法。

    2.1 缩小范围

    我可以在使用MediaQuery的地方嵌套一个Build组件,这样可以让生绘只发生在Build组件内部,进而不影响页面中其它的组件。这种做法相当是缩小了重绘范围。

    2.2 替代方法

    我们还可以使用MediaQuery.sizeof()代替原来的方法,不过这种办法有一定的局限性,比如viewInsetOf方法就没有效果。它仍然会进行生绘。我推测它需要计算
    键盘高度,因此才去重绘。不过只是推测而已,真实的原因还查看源代码才能明白。

    3. 示例代码

     Widget build(BuildContext context) {
        // double screenWidth = MediaQuery.of(context).size.width;
        // double screenHeight = MediaQuery.of(context).size.height;
    
        ///使用下面的方法代替上面的方法,可以减少页面重绘
        double screenWidth = MediaQuery.sizeOf(context).width;
        double screenHeight = MediaQuery.sizeOf(context).height;
        debugPrint("build running");
        ///键盘高度,没有键盘弹出时为0
        // debugPrint("keyboard 1: ${MediaQuery.of(context).viewInsets.bottom}");
        ///这个方法不会减少页面重绘,可见只对sizeof有效果。
        // debugPrint("keyboard 1: ${MediaQuery.viewInsetsOf(context).bottom}");
        ///底部安全区域高度,没有时为0
        // debugPrint("keyboard 2: ${MediaQuery.of(context).viewPadding.bottom}");
        ///没有实际意义
        // debugPrint("keyboard 3: ${MediaQuery.of(context).viewInsets.top}");
        ///顶部状态栏的高度
        // debugPrint("keyboard 4: ${MediaQuery.of(context).viewPadding.top}");
    
        return Scaffold(
         appBar: AppBar(
           title: const Text("Example of Scaffold Overlay"),
         ),
          body: Stack(
            children: [
              Positioned(
                top: 400,
                left: 0,
                ///嵌套一层builder就不会引起页面重绘
                child: Builder(builder: (context) {
                  double y = MediaQuery.of(context).size.height;
                  debugPrint("build running of builder");
                  return Text("check rebuilding value: ${y.toString()}");
                }),
              ),
              ///键盘自动弹出时会导到MediaQuery进行页面重绘,有两种解决方法:更换接口,嵌套builder
              const Positioned(
                top: 450,
                left: 0,
                width: 300,
                height: 56,
                child: TextField(),
              ),
            ],
          ),
        );
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    上面的示例代码中大量使用了MediaQuery类,在页面中包含一个输入框,当我们点击输入框时会自动弹出键盘,此时可以看到代码中添加的日志出现在了运行结果中,
    这表明页面发生了生绘,具体点讲就是build方法在运行,而且会运行多次,输入完成后,点面键盘上的确认键,键盘会自动隐藏,此时也会发生重绘。我们使用上一小
    节介绍的两种优化方法后,再次在输入框中输入内容,此时,页面不会发生重绘。我在这里就不演示具体的运行结果了,建议大家自己动手去实践。

    4. 内容总结

    最后,我们对本章回的内容做一个全面的总结:

    • 页面中使用MediaQuery类后,当键盘自动弹出和隐藏时会引起页面重绘;
    • 使用Build组件来缩小重绘范围,这样可以避免页面发生重绘;
    • 使用MediaQuery中的其它方法可以避免重绘,不过不是所有方法都有效果;
      看官们,与"关于MediaQuery的优化"相关的内容就介绍到这里,欢迎大家在评论区交流与讨论!
  • 相关阅读:
    20230925工作心得
    计算机网络八股
    基于uclinux 的CAN 总线嵌入式驱动编程
    【网络】抓包工具Wireshark下载安装和基本使用教程
    人工智能基础 | 机器学习模型评估与选择(二)
    java面试题(一年工作经验)的心得
    设计模式之美——里式替换原则 和 接口隔离原则
    案例分析-金融业网络安全攻防
    Vu3和React,它们各自的优点和适合的项目类型。
    鼠标右键助手专业版 MouseBoost PRO for Mac v3.3.6中文破解
  • 原文地址:https://blog.csdn.net/talk_8/article/details/137438475