我是 flutter 的新手,当我想在 InitState 中调用我的上下文时,它会抛出一个错误:这是关于
BuildContext.inheritFromWidgetOfExactType
但后来我使用了 didChangeDependencies 并且它可以正常工作。
现在我有两个问题:
1- 为什么在 initState 中调用我们的上下文不起作用,但在从 didChangeDependencies 调用时却起作用?(因为正如我在官方文档中读到的那样This method is also called immediately after [initState],它们都将在构建方法之前被调用。)
2- 为什么我们可以在 build 方法之外访问我们的上下文(因为在那里我们build(BuildContext context)可以使用我们的上下文,但是在 didChangeDependencies 中我们没有类似的东西didChangeDependencies(BuildContext context),所以我们可以从哪里调用上下文来使用它)?
San*_*ngh 47
从状态加载其依赖项的那一刻起,我们就可以使用状态的上下文。
在调用 build 时,上下文对我们可用并作为参数传递。
现在继续,在状态加载其依赖项之前调用 initstate,因此没有可用的上下文,如果您在 initstate 中使用上下文,则会出现错误。但是 didChangeDependencies 在状态加载其依赖项后不久被调用,此时上下文可用,因此您可以在此处使用上下文。
但是,在调用 build 之前调用它们。唯一的区别是,一个在状态加载其依赖项之前调用,另一个在状态加载其依赖项后片刻调用。
fed*_*lov 23
我发现initState和 之间存在显着差异didChangeDependencies:
initState只被调用一次对于小部件didChangeDependencies每个小部件生命周期可能会被多次调用(在我的例子中,当键盘出现/消失时被调用)jit*_*555 15
initState()当新的 Widget 插入到树中时调用。框架将为它创建的每个 [State] 对象调用此方法一次。这将被调用一次,以便执行只需要执行一次的工作,但请记住context不能在此处使用,因为小部件状态被加载,仅initState()完成工作。
句法:
@override
void initState() {
debugPrint('initState()');
super.initState();
}
Run Code Online (Sandbox Code Playgroud)
didChangeDependencies()当此 [State] 对象的依赖项发生更改时调用。
那么,它到底是如何被调用的呢?根据上面的定义,看起来它会在状态改变后被调用,但是我们如何知道状态改变了呢?
例子:
下面的示例使用Provider状态管理机制从父窗口小部件更新子窗口小部件。有Provider一个名为 的属性updateShouldNotify,决定状态是否更改。如果它返回true,则只会didChangeDependencies在课堂上被调用ChildWidget。
updateShouldNotify 在内部默认返回 true,因为它知道状态已更改。那么为什么我们需要 updateShouldNotify 呢?这是需要的,因为如果有人想要在特定条件下更新状态,例如:如果 UI 需要仅显示even值,那么我们可以添加一个条件,例如
updateShouldNotify: (oldValue, newValue) => newValue % 2 == 0,
Run Code Online (Sandbox Code Playgroud)
代码片段:
class ParentWidget extends StatefulWidget {
ParentWidget({Key key, this.title}) : super(key: key);
final String title;
@override
_ParentWidgetState createState() => _ParentWidgetState();
}
class _ParentWidgetState extends State<ParentWidget> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Life Cycle'),
),
body: Provider.value(
value: _counter,
updateShouldNotify: (oldValue, newValue) => true,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Press Fab button to increase counter:',
),
ChildWidget()
],
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
class ChildWidget extends StatefulWidget {
@override
_ChildWidgetState createState() => _ChildWidgetState();
}
class _ChildWidgetState extends State<ChildWidget> {
int _counter = 0;
@override
void initState() {
print('initState(), counter = $_counter');
super.initState();
}
@override
void didChangeDependencies() {
_counter = Provider.of<int>(context);
print('didChangeDependencies(), counter = $_counter');
super.didChangeDependencies();
}
@override
Widget build(BuildContext context) {
print('build(), counter = $_counter');
return Text(
'$_counter',
);
}
}
Run Code Online (Sandbox Code Playgroud)
输出日志:
I/flutter ( 3779): didChangeDependencies(), counter = 1
I/flutter ( 3779): build(), counter = 1
Run Code Online (Sandbox Code Playgroud)
详细解释:
initState()是创建小部件后调用的第一个方法。onCreate()这与Android 或viewDidLoad()iOS 中类似
。
框架第一次构建小部件时,它会调用didChangeDependencies()
after initState()。didChangeDependencies()如果您的状态对象依赖于已更改的继承小部件,它可能会再次调用。
来源:kodeco 发布的 Flutter Apprentice
| 归档时间: |
|
| 查看次数: |
19472 次 |
| 最近记录: |