写在前面
造出BuildContext就是不要使用下面的方法
(context as Element).markNeedsBuild();
Flutter归根究底就是不要我们直接操作Element
基础知识
findAncestorRenderObjectOfType
沿着这个element tree往上找,直到找到一个特定的类型就可以停下
dependOnInheritedWidgetOfExactType
在我现在的组件树的上级,找到离我最近的特定类型的widget,
代码实例
eg:
先来看看整体的代码
Widget build(BuildContext context) {
print(((context as Element).findRenderObject() as RenderBox).size);
return Scaffold(
appBar: AppBar(
title: Text('key的使用'),
),
body: Center(
child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
Text('请按一下按钮,增加数值'),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline1,
),
]),
),
drawer: Drawer(),
floatingActionButton: FloatingActionButton(
onPressed: () {
Scaffold.of(context).openDrawer();
},
child: Icon(Icons.add),
),
);
}
Theme.of(context).textTheme;
//意思就是,从现在的位置开始往上找,找到最近的一个theme,把那个theme传给我.
drawer: Drawer(),
floatingActionButton: FloatingActionButton(
onPressed: () {
Scaffold.of(context).openDrawer();
},
child: Icon(Icons.add),
),
- 运行的时候就会出现报错
Another exception was thrown: Scaffold.of() called with a context that does not contain a Scaffold.
//在不包含Scaffold的上下文中调用Scaffold.of()。
此时,Scaffold.of(context).openDrawer();
,确实往上找的时候,确实找不到自己上级
这个时候,我们可以把floatingActionButton 的点击事件给抽离出来,这样的话,就相当于给Scaffold.of(context).openDrawer();
包了一层
drawer: Drawer(),
floatingActionButton: Foo(),
class Foo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FloatingActionButton(
onPressed: () {
Scaffold.of(context).openDrawer();
},
child: Icon(Icons.add),
);
}
}
在以上的代码中,我们并不想得到一个新的widget,那么我们就可以接着往下操作.
使用LayoutBuilder
,就会重建一个context
,这里我们将context
换个写法ctx
,以防混淆
BoxConstraints
:有多少可用空间
drawer: Drawer(),
floatingActionButton: LayoutBuilder(
builder: (BuildContext ctx, BoxConstraints constraints) {
return FloatingActionButton(
onPressed: () {
Scaffold.of(ctx).openDrawer();
},
child: Icon(Icons.add),
);
},
),
当然,LayoutBuilder
是能够获取当前布局最大空间位置的容器,
此时,我们本demo用不到LayoutBuilder
的时候,怎么办呢?
看下面:
drawer: Drawer(),
floatingActionButton: Builder(
builder: (BuildContext ctx) {
return FloatingActionButton(
onPressed: () {
Scaffold.of(ctx).openDrawer();
},
child: Icon(Icons.add),
);
},
),