从其他类调用父窗口小部件中的setState

时间:2019-09-16 05:55:15

标签: flutter

请考虑在listViewBuilder中使用以下listTile的onTap函数:

onTap: () {
  Navigator.of(context).push(
    MaterialPageRoute(builder: (context) => Chat(id: uid, peerId: peerId, avatar: "",
      peerAvatar: avatar, peerName: name))).then((_) {
    setState(() {
      getChatUsers();
    });
  });
},

基本上,它正在推送一个新屏幕,当该屏幕弹出时,它将刷新listviewbuilder。当listTile与getChatUsers()在同一StateFullWidget下时,此方法很好用,但是我需要在另一个Widget中构建listTile,因为另一个类中的另一个ListviewBuilder也需要访问它(showSearch委托> buildSuggestions)。但是这样做并不能再让我访问:

setState(() {
  getChatUsers();
});

需要一些帮助找出解决方案。

3 个答案:

答案 0 :(得分:1)

C提取到另一个小部件中后(这是正确的方法),您将不得不在Child say ListTile中添加一个属性,并将child的实现更改如下:

final VoidCallback onTap;

所有导航或在异步回调中执行某些操作的逻辑都应由父级处理,因为子级将是一个愚蠢的无状态小组件。它不应该控制单击被触发时应发生的情况。这样会降低子窗口小部件的可重用性。

答案 1 :(得分:0)

我一直在寻找一个简单的解决方案,但最终我得到了scopedmodel方法。将应用程序包装在scopedmodel UserModel中,然后包装在UserModel类中:

QuerySnapshot chatUsers;
Future getChatUsers() async {

  final QuerySnapshot chatters = await Firestore.instance.collectionGroup('NewMessages').where('chatters', arrayContains: firebaseUser.uid)
    .orderBy("timestamp", descending: true)
    .getDocuments();

  chatUsers = chatters;
  notifyListeners();
  
  return chatters;

}
所以现在当弹出的屏幕弹出时,我可以使用它:

Navigator.of(context).push(
  MaterialPageRoute(builder: (contexto) => Chat(id: uid, peerId: peerId, avatar: "",
    peerAvatar: avatar, peerName: name))).then((_) async {
  conversaUsers = await UserModel.of(contexto).getChatUsers();
});

到处都有一个ListviewBuilder等待新数据(例如在父Build和searchdelegate buildsuggestions中,我现在可以这样做:

final QuerySnapshot chatUsers = ScopedModel.of < UserModel > (context, rebuildOnChange: true)
  .chatUsers;
我知道有些人可能想知道为什么我不仅仅为了更新Listview Builders而去使用streambuilder左右,但这是因为我首先需要处理从Firestore返回的数据集,然后再将其发送给ListView Builders。

答案 2 :(得分:-1)

实现此目的的另一种方法是将Parent Widget State传递给ChildWidget,然后使用该Parent Widget可以调用该函数。这是相同的示例。


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();
        },
      ),
    );
  }
}