flutter - 子widget的build方法后触发的设置父widget状态的回调不会触发其父widget的build方法
问题描述
我有一个名为(对于这个片段)MainLayout 的父小部件和一个名为 ChildWidget 的子小部件。在执行其构建方法后,我想在子组件的父小部件的 AppBar 的操作中添加一个 IconButton。父项的 AppBar 中显示的操作存储在其状态中。
我使用的方法有问题:在子小部件的构建方法之后触发的回调以设置其父小部件的状态不会触发其父小部件的构建方法,但状态(父)已更改。因此,搜索图标没有挂载在 MainLayout 的 AppBar 的操作中。
为什么要以这种方式工作以及如何解决?
下面的代码是我的子小部件和父小部件的示例:
child_widget.dart:
class ChildWidget extends StatelessWidget {
// Add a search button in the AppBar of MainLayout widget.
void _updateAppBar(BuildContext context) async {
InheritedMainLayout.of(context).appBar.updateActions(<Widget>[
IconButton(
icon: Icon(Icons.search),
onPressed: () => showSearch(
context: context,
delegate: SearchPageDelegate(),
),
),
]);
}
@override
Widget build(BuildContext context) {
_updateAppBar(context);
return Container(
width: 100,
height: 100,
color: Colors.blue,
);
}
}
parent_widget.dart:
class ParentWidget extends StatefulWidget {
@override
_ParentWidgetState createState() => new _ParentWidgetState();
}
class _ParentWidgetState extends State<ParentWidget> {
// This is the method that is passed as a parameter to the ChildWidget to update the actions of the AppBar.
void _updateAppBarActions(List<Widget> actions) =>
setState(() => _appBarActions = actions);
@override
Widget build(BuildContext context) {
return InheritedMainLayout( // The inherited widget used to use the _updateAppBarActions method in the child widget
appBar: new AppBarConfig(
actions: _appBarActions,
),
child: Scaffold(
appBar: AppBar(
title: Text("Title of the App"),
actions: _appBarActions, // Actions showed in the AppBar are from the state, _appBarActions
),
body: Padding(
padding: EdgeInsets.all(20.0),
child: _currentChild, // Here is loaded the builded widget called ChildWidget.
),
drawer: AppDrawer(
items: _drawerItems,
onTap: _onChangePage,
),
),
);
}
}
解决方案
您可能会看到此问题,因为您无法在构建过程中调用 setState。您可以使用 addPostFrameCallback 方法在构建过程之后调用您的回调。例如,请参阅此问题的答案Calling setState() during build without user interaction。
推荐阅读
- node.js - 如何使用事务或批处理来读取更新的值,然后使用该值执行更多更新?
- arrays - 从数组中显示带有名称的随机图像。(斯威夫特用户界面)
- javascript - 尝试从 json 文件中获取数据时出现问题
- wordpress - 如何在wordpress中编辑隐藏表单
- python - Django:生产中的登录/密码管理?
- node.js - 无法从 lambda 函数的 dynamodb 获取数据
- android - MediaStore.ACTION_IMAGE_CAPTURE 的结果始终为 -1,但不返回任何数据
- android - 如何从 firebase 查询此数据并设置为 FirebaseRecyclerOptions
- c# - Global.asax 和 MasterPage 之间会发生什么?
- php - 当我选择等级时,如何从表 gaji 中获取 gaji