flutter setstate只重建一个子项



在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
],
),
),
);

我预计当我按下"+"按钮时,只有第二个小部件会被重新构建,但现在它会重新构建堆栈的所有内容。

谢谢大家。

另一个选项是使用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(""),
],
);
}),
),
);
}
}

从官方文档中,我们可以阅读:

";当对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;
});
),
],
), 
}

然后在你的脚手架上叫它:

Scaffold(
appBar: MyAppBar(), 

我可以建议的其他方法是使用ValueNotificationernotifyListeners((。请阅读本页,避免重复重建所有小部件。解释得很好。

您可以使用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("");
},
)
],
),
),
);
}

从您不想更改的小部件中删除setState。并且只使用setState来重建

或者您可以考虑使用inheritedModel小部件

以下是一个示例,您可以从中学习如何构建继承模型小部件,以仅更新特定的小部件,而不是整个小部件。

https://medium.com/flutter-community/flutter-state-management-setstate-fn-is-the-easiest-and-the-most-powerful-44703c97f035

相关内容

最新更新