sha*_*ais 21
只需在您的一个高级小部件上使用一个键,下面的所有内容都会丢失状态:
Key _refreshKey = UniqueKey();
void _handleLocaleChanged() => setState((){
_refreshKey = UniqueKey()
});
Widget build(BuildContext context){
return MaterialApp(
key: _refreshKey ,
...
)
}
Run Code Online (Sandbox Code Playgroud)
您还可以使用值键,例如:
return MaterialApp(
key: ValueKey(locale.name)
...
);
Run Code Online (Sandbox Code Playgroud)
Col*_*son 18
这种类型的用例,你有孩子可以阅读的数据,但你不想显式地将数据传递给你所有孩子的构造函数参数,通常需要一个InheritedWidget.Flutter将自动跟踪哪些小部件依赖于数据并重建已更改的树的部分.有一个LocaleQuery用于处理区域设置更改的小部件,您可以在Stocks示例应用程序中查看它的使用方式.
简而言之,这就是Stocks正在做的事情:
StocksApp)上进行回调以处理区域设置更改.这个回调做了一些工作,然后返回一个自定义的实例LocaleQueryDataonLocaleChanged参数MaterialAppLocaleQuery.of(context).如果要跟踪区域设置更改以外的其他内容,可以创建自己的扩展类InheritedWidget,并将其包含在应用程序根目录附近的层次结构中.它的父母应该是一个StatefulWidget关键设置为GlobalKey儿童可以访问的.该State的StatefulWidget应该自己要分发和揭露改变它该呼叫的数据保护方法setState.如果子窗口小部件想要更改State数据,则可以使用全局键获取指向State(key.currentState)的指针并在其上调用方法.如果他们想要读取数据,他们可以调用of(context)子类的静态方法,InheritedWidget这将告诉Flutter这些小部件需要在您的State调用时重建setState.
Mar*_*rcG 17
老问题,但这是解决方案:
在您的build方法中,调用该rebuildAllChildren函数并将其传递给context:
@override
Widget build(BuildContext context) {
rebuildAllChildren(context);
return ...
}
void rebuildAllChildren(BuildContext context) {
void rebuild(Element el) {
el.markNeedsBuild();
el.visitChildren(rebuild);
}
(context as Element).visitChildren(rebuild);
}
Run Code Online (Sandbox Code Playgroud)
这将访问所有儿童并将他们标记为需要重建。如果您将此代码放在小部件树中最顶层的小部件中,它将重建所有内容。
另请注意,您必须订购要重建的特定小部件。此外,您可以使用一些布尔值,以便该小部件的重建仅在您真正需要它时才重建其所有子项(当然,这是一项昂贵的操作)。
重要提示:这是一种黑客行为,只有在您知道自己在做什么并且有充分的理由时才应该这样做。我的国际化包中有一个必要的例子:i18_extension。正如科林杰克逊在他的回答中解释的那样,你真的不应该这样做。
Tab*_*aba 11
刷新整个小部件树可能很昂贵,而且当您在用户眼前这样做时,这看起来并不好。
所以为此目的扑了ValueListenableBuilder<T> class。它允许您只重建一些您的目的所必需的小部件,而跳过昂贵的小部件。
您可以在此处查看文档ValueListenableBuilder flutter docs
或仅查看以下示例代码:
return Scaffold(
appBar: AppBar(
title: Text(widget.title)
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('You have pushed the button this many times:'),
ValueListenableBuilder(
builder: (BuildContext context, int value, Widget child) {
// This builder will only get called when the _counter
// is updated.
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text('$value'),
child,
],
);
},
valueListenable: _counter,
// The child parameter is most helpful if the child is
// expensive to build and does not depend on the value from
// the notifier.
child: goodJob,
)
],
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.plus_one),
onPressed: () => _counter.value += 1,
),
);
Run Code Online (Sandbox Code Playgroud)
也永远不会忘记的力量 setState(() {});
Tos*_*ade 10
简单使用:
Navigator.popAndPushNamed(context,'/screenname');
Run Code Online (Sandbox Code Playgroud)
每当您需要刷新时 :)
您的窗口小部件应具有setState()方法,每次调用此方法时,将重绘窗口小部件。
可能对您的用例有用的是使用导航器重新加载页面。我在我的应用程序中在“真实”和“演示”模式之间切换时会这样做。这是一个例子:
Navigator.of(context).push(
new MaterialPageRoute(
builder: (BuildContext context){
return new SplashPage();
}
)
);
Run Code Online (Sandbox Code Playgroud)
您可以将上面代码中的“new SplashPage()”替换为您想要重新加载的任何主要小部件(或屏幕)。可以从您有权访问 BuildContext 的任何位置(这是 UI 中的大多数位置)调用此代码。
我在这篇文章中解释了如何创建自定义的“ AppBuilder”小部件。
您可以通过将其与MaterialApp一起包装来使用该小部件,例如:
Widget build(BuildContext context) {
return AppBuilder(builder: (context) {
return MaterialApp(
...
);
});
}
Run Code Online (Sandbox Code Playgroud)
您可以使用以下命令告诉应用重新生成:
AppBuilder.of(context).rebuild();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
25381 次 |
| 最近记录: |