Flutter知识集

  1. BuildContext
  2. Widget的绘制
  3. 事件传递机制
  4. 手势
  5. key的作用
  6. 框架原理
  7. Builder里的context的源头
  8. Key的作用

七、Builder里的context是包裹这个BuilderWidgetcontext,每个Widget都有自己的context,举个例子:

image.png

上图中builder: (context)参数里的context是Positioned的context
这个概念很重要,因为如果你使用Scaffold.of(context).showSnackBar方法显示SnackBar的话,使用错了context会报错,因为你使用的context可能不包含Scaffold,系统找不到就报错了,系统源码如下:

//scaffold.dart
  static ScaffoldState of(BuildContext context, { bool nullOk = false }) {
    assert(nullOk != null);
    assert(context != null);
    final ScaffoldState result = context.ancestorStateOfType(const TypeMatcher<ScaffoldState>());
    if (nullOk || result != null)
      return result;
    throw FlutterError(
      'Scaffold.of() called with a context that does not contain a Scaffold.\n'
      'No Scaffold ancestor could be found starting from the context that was passed to Scaffold.of(). '
      'This usually happens when the context provided is from the same StatefulWidget as that '
      'whose build function actually creates the Scaffold widget being sought.\n'
      'There are several ways to avoid this problem. The simplest is to use a Builder to get a '
      'context that is "under" the Scaffold. For an example of this, please see the '
      'documentation for Scaffold.of():\n'
      '  https://docs.flutter.io/flutter/material/Scaffold/of.html\n'
      'A more efficient solution is to split your build function into several widgets. This '
      'introduces a new context from which you can obtain the Scaffold. In this solution, '
      'you would have an outer widget that creates the Scaffold populated by instances of '
      'your new inner widgets, and then in these inner widgets you would use Scaffold.of().\n'
      'A less elegant but more expedient solution is assign a GlobalKey to the Scaffold, '
      'then use the key.currentState property to obtain the ScaffoldState rather than '
      'using the Scaffold.of() function.\n'
      'The context used was:\n'
      '  $context'
    );
  }
//framework.dart
  @override
  State ancestorStateOfType(TypeMatcher matcher) {
    assert(_debugCheckStateIsActiveForAncestorLookup());
    Element ancestor = _parent;
    while (ancestor != null) {
      if (ancestor is StatefulElement && matcher.check(ancestor.state))
        break;
      ancestor = ancestor._parent;
    }
    final StatefulElement statefulAncestor = ancestor;
    return statefulAncestor?.state;
  }

可以看到framework.dart文件里的ancestorStateOfType方法会从参数context寻找匹配的类型,也就是TypeMatcher<ScaffoldState>中的泛型类型ScaffoldState,找不到就抛出了异常。

八、Key的作用
https://segmentfault.com/a/1190000011276853

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,175评论 1 32
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,312评论 4 61
  • 首先,来分享我们和小花样花酒的缘分。缘起于2016年11月12日的中午,大圣老板和大韦老板在一个饭局里面偶然碰到一...
    安吉拉杜阅读 845评论 0 0
  • 昨晚回妈家吃饭,回来已经快10点,还有2集《水浒传》没看,一进门儿子直奔电脑间,开始了今天的作业,看完大约已经12...
    李宇航妈妈阅读 283评论 0 2
  • 最近有点烦,思想太消极了。←_←
    轻叹微盼阅读 134评论 0 0