Joh*_*ohn 3 dart flutter flutter-layout
在flutter中我需要当我调用setstate时,它只重建一个小部件
我将两个孩子放在一堆中,我需要当按下按钮时,只重建第二个孩子。
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
],
),
),
);
Run Code Online (Sandbox Code Playgroud)
我预计当我按下“+”按钮时,只会重新构建第二个小部件,但现在它将重建堆栈的所有内容。
谢谢你们。
从官方文档我们可以读到:
“当在 State 上调用 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;
});
),
],
),
}
Run Code Online (Sandbox Code Playgroud)
然后在你的脚手架中调用它:
Scaffold(
appBar: MyAppBar(),
Run Code Online (Sandbox Code Playgroud)
我可以建议的其他方法是使用ValueNotifier或notifyListeners()。请阅读此页避免重复重建所有小部件。这是很好解释的。
另一种选择是使用 ValueListenableBuilder:
class _MyHomePageState extends State<MyHomePage> {
final ValueNotifier<bool> popup = ValueNotifier<bool>(false);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('TEST'),
actions: <Widget>[
IconButton(
// + BUTTON
icon: Icon(Icons.add),
onPressed: () {
popup.value = true;
}),
IconButton(
// - BUTTON
icon: Icon(Icons.remove),
onPressed: () {
popup.value = false;
})
],
),
body: Center(
child: ValueListenableBuilder<bool>(
valueListenable: popup,
builder: (context, value, _) {
return Stack(
children: [
Text("Random - " + new Random().nextInt(20).toString()),
popup.value ? Center(child: Text("abc")) : Text(""),
],
);
}),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9977 次 |
| 最近记录: |