• flutter context踩坑


    下面代码有三个button,内容都是一样的,只不过包装方式不同。

    第一个是没有包装的,第二个用Builder包了一层,第三个封装成了StatelessWidget。

    运行一下,第一个button会报如下错误:

    是说调用的Scaffod.of(context)找不到Scaffold。

    import 'package:flutter/material.dart';
    
    void main() => runApp(BuilderApp());
    
    class BuilderApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: BuilderHomePage(),
        );
      }
    }
    
    class BuilderHomePage extends StatefulWidget {
      @override
      _BuilderHomePageState createState() => _BuilderHomePageState();
    }
    
    class _BuilderHomePageState extends State<BuilderHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("Hello"),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                RaisedButton(
                  onPressed: () {
                    Scaffold.of(context).showSnackBar(
                        new SnackBar(content: Text("Hello  SnackBar1")));
                  },
                  child: Text("Test"),
                ),
                Builder(
                  builder: (BuildContext context) {
                    return RaisedButton(
                      onPressed: () {
                        Scaffold.of(context).showSnackBar(
                            new SnackBar(content: Text("Hello  SnackBar2")));
                      },
                      child: Text("Builder SnackBar"),
                    );
                  },
                ),
                WidgetTest()
              ],
            ),
          ),
        );
      }
    }
    
    
    class WidgetTest extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Container(
          child:     RaisedButton(
            onPressed: () {
              Scaffold.of(context).showSnackBar(
                  new SnackBar(content: Text("Hello  SnackBar3")));
            },
            child: Text("No Builder SnackBar"),
          ),
        );
      }
    }

    分析一下:

    这是Scaffold.of(context)的源码

    可以看到这个方法返回的是findAncestorStateOfType()。其实所有.of(context).xxx这样的方法都是调用这个东西。

    点进去看看:

    可以看到这个方法是在依次向上遍历该widget的祖先,直到找到一个符合参数类型的祖先就退出。

    注意最开始赋值是把当前widget的_parent赋给了ancestor,所以是从当前widget的父节点开始找的。

    那么就很容易判断了:

    第一个button的context复用了build函数的context(android studio很贴心的会高亮两个context的连接关系) 

    第二个button用Builder套了一层,它的context是Builder的builder函数的参数context

     第三个button的context是StatelessWidget的build函数参数的context,就不截图了。

    由于第一个button的context和scaffold是同一个,所以从它的_parent往上找肯定找不到scaffold,所以报错。

    另外两个button都是scaffold的子节点,他俩的_parent恰好就是scaffold,所以不会报错。

  • 相关阅读:
    揭秘重度MMORPG手游后台性能优化方案
    算法:贪心、回溯(su)、分治、动态规划,思想简要
    表单提交 curl和浏览器方式
    mysql 聚集索引,非聚集索引,覆盖索引区别。
    虚拟机中的Linux不能上网
    第二篇 界面开发 (Android学习笔记)
    第一篇 入门必备 (Android学习笔记)
    C/C++知识补充 (1)
    向后/向前引用, 零宽断言, 转义, 命名分组
    C/C++知识补充(2) C/C++操作符/运算符的优先级 & 结合性
  • 原文地址:https://www.cnblogs.com/FdWzy/p/13515228.html
Copyright © 2020-2023  润新知