Flutter 从其他类调用父窗口小部件中的setState 请考虑ListVIEW Buudid:/P>内部列表中的以下OTAP函数
Flutter 从其他类调用父窗口小部件中的setState 请考虑ListVIEW Buudid:/P>内部列表中的以下OTAP函数,flutter,Flutter,onTap:(){ 导航器.of(上下文).push( MaterialPage路由(生成器:(上下文)=>聊天(id:uid,peerId:peerId,化身:“”, peerAvatar:avatar,peerName:name))。然后(){ 设置状态(){ getChatUsers(); }); }); },当您将ListTile提取到另一个小部件中(这是正确的方法)时,您必须在Child sayfinal VoidCallback onTap中添加属性并将子项的实现更改为以下内容: o
onTap:(){
导航器.of(上下文).push(
MaterialPage路由(生成器:(上下文)=>聊天(id:uid,peerId:peerId,化身:“”,
peerAvatar:avatar,peerName:name))。然后(){
设置状态(){
getChatUsers();
});
});
},
当您将ListTile
提取到另一个小部件中(这是正确的方法)时,您必须在Child sayfinal VoidCallback onTap中添加属性
并将子项的实现更改为以下内容:
onTap: onTap,
所有在异步回调中导航或执行操作的逻辑都应该由父级处理,因为子级将是一个无状态的小部件。它不应该控制当点击被触发时会发生什么。这降低了子窗口小部件的可重用性。另一种方法是将父窗口小部件状态传递给子窗口小部件,并使用该父窗口小部件调用该函数。下面是同样的例子
class ParentWidget extends StatefulWidget {
@override
ParentWidgetState createState() => ParentWidgetState();
}
class ParentWidgetState extends State<ParentWidget> {
String title = 'Parent';
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(child: Text(title)),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.navigate_next),
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => ChildWidget(this)));
},
),
);
}
void changeMsg() {
setState(() {
title = 'Parent 2';
});
}
}
class ChildWidget extends StatefulWidget {
ChildWidget({this.parentWidgetState});
final ParentWidgetState parentWidgetState;
@override
_ChildWidgetState createState() => _ChildWidgetState();
}
class _ChildWidgetState extends State<ChildWidget> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(child: Text('Child')),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.done),
onPressed: () {
widget.parentWidgetState.changeMsg();
},
),
);
}
}
类ParentWidget扩展了StatefulWidget{
@凌驾
ParentWidgetState createState()=>ParentWidgetState();
}
类ParentWidgetState扩展了状态{
字符串标题='父';
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:中间(子项:文本(标题)),
浮动操作按钮:浮动操作按钮(
子:图标(图标。导航到下一步),
已按下:(){
Navigator.push(上下文,
MaterialPage路由(生成器:(上下文)=>ChildWidget(this));
},
),
);
}
void changeMsg(){
设置状态(){
标题=‘父2’;
});
}
}
类ChildWidget扩展StatefulWidget{
ChildWidget({this.parentWidgetState});
最终ParentWidgetState ParentWidgetState;
@凌驾
_ChildWidgetState createState()=>\u ChildWidgetState();
}
类_ChildWidgetState扩展状态{
@凌驾
小部件构建(构建上下文){
返回脚手架(
主体:居中(子对象:文本(“子对象”),
浮动操作按钮:浮动操作按钮(
子:图标(Icons.done),
已按下:(){
widget.parentWidgetState.changeMsg();
},
),
);
}
}
我一直在寻找一个简单的解决方案,但最终还是采用了scopedmodel方法。将应用程序包装在scopedmodel UserModel中,然后包装在UserModel类中:
QuerySnapshot聊天用户;
未来的getChatUsers()异步{
final QuerySnapshot chatters=wait Firestore.instance.collectionGroup('NewMessages')。其中('chatters',arrayContains:firebaseUser.uid)
.orderBy(“时间戳”,降序:true)
.getDocuments();
聊天用户=聊天者;
notifyListeners();
回话;
}
因此基本上您希望从ChildStatefulWidget
重建ParentStatefulWidget
。是这样吗?谢谢你花时间把这个示例代码放在一起。但在这里,您将从父statefull小部件中推送新屏幕,而我的要求是将其推送到一个独立的小部件中,该小部件可以由父小部件(本例中为listview builder)和连接到父小部件的其他类调用(在本例中为searchdelegate buildsuggestions。我尝试了您的方法,但在调用widget.parentWidgetState.changeMsg()时抛出了NoSuchMethod错误);我最终使用scopedmodel解决了我的问题,如答案所示。我最终使用了scopedmodel,如答案所示,但如果您想用一个示例详细说明,我可能正在学习一两个新东西。