Flutter BuilderContext 找不到页面中的元素

2020-06-18  本文已影响0人  戴维王

错误提示

The following assertion was thrown while handling a gesture:
Scaffold.of() called with a context that does not contain a Scaffold.

出错代码如下:

class WidgetRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('WidgetRoute'),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            FlatButton(
                child: Text('显示SnackBar'),
                onPressed: () {
                  // 获取Scaffold对象的State用于显示底部通知栏SnackBar
                  Scaffold.of(context)
                      ?.showSnackBar(SnackBar(content: Text('我是SnackBar')));
                }),
          ],
        ),
      ),
    );
  }
}

错误分析

按照上述代码点击按钮希望展示SnackBar时就会出现“context that does not contain a Scaffold”的错误,原因很简单,就是我们使用的context并不是子widget的context而是WidgetRoute构建时传入的context,Scaffold.of(context)的实现方式是从传入的context对应的widget向上遍历widget树并返回最近的ScaffoldState,我们用WidgetRoute的context自然是找不到子布局中的SnackBar。

解决办法:

既然我们使用的是错误的context那么只要确保使用当前widget的context就可以了

class WidgetRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('WidgetRoute'),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            Builder(
              builder: (context) {
                return FlatButton(
                    child: Text('显示SnackBar'),
                    onPressed: () {
                      Scaffold.of(context)
                          ?.showSnackBar(SnackBar(content: Text('我是SnackBar')));
                    });
              },
            ),
          ],
        ),
      ),
    );
  }
}

Scaffold.of()只是用来举例说明的,我们在使用context跨组件获取对象时:

ancestorInheritedElementForWidgetOfExactType(Type targetType) 获取 InheritedElement

ancestorRenderObjectOfType(TypeMatcher matcher) 获取RenderObject

ancestorStateOfType(TypeMatcher matcher) 获取 State

ancestorWidgetOfExactType(Type targetType) 获取 Widget

findRenderObject() 获取 RenderObject

inheritFromElement(InheritedElement ancestor, { Object aspect }) 获取 InheritedWidget

inheritFromWidgetOfExactType(Type targetType, { Object aspect }) 获取 InheritedWidget

rootAncestorStateOfType(TypeMatcher matcher) 获取 State

visitAncestorElements(bool visitor(Element element)) 获取 void

visitChildElements(ElementVisitor visitor) 获取 void

都有可能出现上述错误。

上一篇 下一篇

猜你喜欢

热点阅读