在扑朔迷离中,我需要在调用setstate时仅重建一个小部件
我将2个孩子堆叠在一起,我需要在按下按钮时,仅重建第二个孩子。
bool popup = false;
Scaffold(
appBar: AppBar(
title: const Text('TEST'),
actions: <Widget>[
IconButton( // + BUTTON
icon: Icon(Icons.add),
onPressed: () {
setState(() {
popup = true;
});
},
),
IconButton( // - BUTTON
icon: Icon(Icons.remove),
onPressed: () {
setState(() {
popup = false;
});
),
],
),
body: SafeArea(
child: Stack(
children: <Widget>[
Container( // FIRST WIDGET
key: ValueKey(1),
child: Text("Random - "+new Random().nextInt(20).toString())
),
popup ? Center(child: Text("abc")) : Text("") , // SECOND WIDGET
],
),
),
);
我希望当我按下“ +”按钮时,只会重新构建第二个小部件,但是现在它将重新构建堆栈的所有内容。
谢谢大家。
答案 0 :(得分:0)
从您不想更改的小部件中删除setState。并且只将setState用于您需要重建的那些
或者您可以考虑使用InheritedModel小部件
答案 1 :(得分:0)
这里是一个示例,您可以在其中学习如何构建继承的模型小部件以仅更新特定的小部件而不是整个小部件。
答案 2 :(得分:0)
您可以使用StreamBuilder:
StreamController<bool> popup = StreamController<bool>();
@override
void dispose() {
popup.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('TEST'),
actions: <Widget>[
IconButton( // + BUTTON
icon: Icon(Icons.add),
onPressed: () => popup.add(true),
),
IconButton( // - BUTTON
icon: Icon(Icons.remove),
onPressed: () => popup.add(false),
),
],
),
body: SafeArea(
child: Stack(
children: <Widget>[
Container( // FIRST WIDGET
key: ValueKey(1),
child: Text("Random - "+new Random().nextInt(20).toString())
),
StreamBuilder<bool>(
stream: popup.stream,
initialData: false,
builder: (cxt, snapshot) {
return snapshot.data ? Center(child: Text("abc")) : Text("");
},
)
],
),
),
);
}
答案 3 :(得分:0)
从official docs我们可以读到:
“在状态上调用setState()时,所有后代小部件都将重建。因此,请将setState()本地化为实际上需要更改UI的子树部分。避免将setState()向上调用如果更改只包含在树的一小部分,则在树中显示。”
我的建议(我经常使用)是将您要在新的StatefulWidget中重建的小部件分开。这样,仅setState将重新构建该小部件。
class MyAppBar extends StatefulWidget
...
class _MyAppBarState extends State<MyAppBar> {
bool popup = false;
@override
Widget build(BuildContext context) {
return AppBar(
title: const Text('TEST'),
actions: <Widget>[
IconButton( // + BUTTON
icon: Icon(Icons.add),
onPressed: () {
setState(() {
popup = true;
});
},
),
IconButton( // - BUTTON
icon: Icon(Icons.remove),
onPressed: () {
setState(() {
popup = false;
});
),
],
),
}
然后在您的支架中调用它:
Scaffold(
appBar: MyAppBar(),
我建议使用的其他方法是使用 ValueNotifier 或 notifyListeners()。请阅读此页面Avoid rebuilding all the widgets repetitively。解释得很好。