zoukankan      html  css  js  c++  java
  • 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,所以不会报错。

  • 相关阅读:
    AWS 免费套餐
    UWP DEP0700: 应用程序注册失败。[0x80073CF9] 另一个用户已安装此应用的未打包版本。当前用户无法将该版本替换为打包版本。
    UWP 应用程序名称本地化以及商店显示名称本地化
    ES6知识整理(6)--Symbol函数
    【web前端】移动端控制台插件,手机端页面查看相关页面控制台信息
    ES6知识整理(5)--对象的扩展
    ES6知识整理(4)--数组的扩展
    【移动端web】软键盘兼容问题
    ES6知识整理(3)--函数的扩展
    ES6知识整理(2)--变量的解构赋值
  • 原文地址:https://www.cnblogs.com/FdWzy/p/13515228.html
Copyright © 2011-2022 走看看