Flutter知识集

2018-12-21  本文已影响46人  o动感超人o
  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

上一篇下一篇

猜你喜欢

热点阅读