从Flutter中暂时从树中删除时保留小部件状态 [英] Preserve widget state when temporarily removed from tree in Flutter
问题描述
我正在尝试保留小部件的状态,因此,如果我从小部件树中暂时删除有状态的小部件,然后在以后重新添加它,则该小部件将具有与我之前相同的状态删除它.这是我的简化示例:
I'm trying to preserve the state of a widget, so that if I temporarily remove the stateful widget from the widget tree, and then re-add it later on, the widget will have the same state as it did before I removed it. Here's a simplified example I have:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool showCounterWidget = true;
@override
Widget build(BuildContext context) {
return Material(
child: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
showCounterWidget ? CounterButton(): Text("Other widget"),
SizedBox(height: 16,),
FlatButton(
child: Text("Toggle Widget"),
onPressed: (){
setState(() {
showCounterWidget = !showCounterWidget;
});
},
)
],
),
),
);
}
}
class CounterButton extends StatefulWidget {
@override
_CounterButtonState createState() => _CounterButtonState();
}
class _CounterButtonState extends State<CounterButton> {
int counter = 0;
@override
Widget build(BuildContext context) {
return MaterialButton(
color: Colors.orangeAccent,
child: Text(counter.toString()),
onPressed: () {
setState(() {
counter++;
});
},
);
}
}
理想情况下,我不希望重置状态,因此计数器不会重置为0,我如何保存计数器小部件的状态?
Ideally, I would not want the state to reset, therefor the counter would not reset to 0, how would I preserve the state of my counter widget?
推荐答案
小部件暂时从树中删除时,其状态会松散的原因,正如约书亚所说,是因为它的元素/状态会松散.
The reason why the widget loose its state when removed from the tree temporarily is, as Joshua stated, because it loose its Element/State.
现在您可能会问:
我是否可以缓存元素/状态,以便下次插入窗口小部件时,可以重用前一个窗口小部件,而不是重新创建它们?
Can't I cache the Element/State so that next time the widget is inserted, it reuse the previous one instead of creating them anew?
这是一个有效的主意,但不是.你不能Flutter认为这是一种反模式,在这种情况下会抛出异常.
This is a valid idea, but no. You can't. Flutter judges that as anti-pattern and will throw an exception in that situation.
您应该做的是将窗口小部件保持在窗口小部件树中处于禁用状态.
What you should instead do is to keep the widget inside the widget tree, in a disabled state.
要实现这种目标,您可以使用以下小部件:
To achieve such thing, you can use widgets like:
- IndexedStack
- 可见性/台下
这些小部件将允许您将小部件保留在小部件树中(以便保持其状态),但是禁用其渲染/动画/语义.
These widgets will allow you to keep a widget inside the widget tree (so that it keeps its state), but disable its rendering/animations/semantics.
因此,而不是:
Widget build(context) {
if (condition)
return Foo();
else
return Bar();
}
这会使 Foo
/ Bar
在它们之间切换时失去状态
which would make Foo
/Bar
loose their state when switching between them
这样做:
IndexedStack(
index: condition ? 0 : 1, // switch between Foo and Bar based on condition
children: [
Foo(),
Bar(),
],
)
使用此代码,然后 Foo
/ Bar
在它们之间来回移动时,不会松开它们的状态.
Using this code, then Foo
/Bar
will not loose their state when doing a back and forth between them.
这篇关于从Flutter中暂时从树中删除时保留小部件状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!