当另一个小部件的状态改变时重建小部件

Posted

技术标签:

【中文标题】当另一个小部件的状态改变时重建小部件【英文标题】:Rebuild widget when another widget's state changes 【发布时间】:2018-03-19 03:21:01 【问题描述】:

在 MyHomePage 状态小部件中,我有一个 DropDownButton 和一个 ListView。我正在尝试根据选定的 DropDownMenuItem 重建 ListView。但是,我在填充 ListView 时遇到问题。我必须转到另一个视图,然后返回 MyHomePage 才能显示数据。

我的主页状态:

class _MyHomePageState extends State<MyHomePage> 
 final List<String> _dow = [
  'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'
 ].toList();

 @override
 void initState() 
  selectedDow = _dow.first;
  super.initState();


 @override
 Widget build(BuildContext context) 
  final _dowOptions = _dow.map((String day) =>
  new DropdownMenuItem(value: day, child: new Text(day))).toList();

  return new Scaffold(
   appBar: new AppBar(
    title: new DropdownButton(
        value: selectedDow, items: _dowOptions, onChanged: (s) 
      setState(() 
        selectedDow = s;
      
      );
    ),
    actions: <Widget>[
      new IconButton(icon: new Icon(Icons.edit), onPressed: () ),
      new IconButton(icon: new Icon(Icons.add), onPressed: () 
        newItem();
      )
    ],
  ),
  body: new DisplayList(),
  floatingActionButton: new FloatingActionButton(
      child: new Icon(Icons.add), onPressed: editItem),
);


显示列表:

class DisplayList extends StatefulWidget 
 DisplayList(Key key) : super(key: key);

 @override
 _DisplayListState createState() => new _DisplayListState();


class _DisplayListState extends State<DisplayList> 

 List<DataModel> dowList = new List<DataModel>();
 String currentCollection = selectedDow.toLowerCase();

 @override
 void initState() 
  updateList();
  super.initState();


 updateList() 
  Firestore.instance
    .collection(currentCollection)
    .snapshots
    .listen((snapshot) 
   for (var doc in snapshot.documents) 
    Firestore.instance.collection(doc['colPath'])
        .document(doc['docId'])
        .get()
        .then((docSnap) 
      String docId = docSnap.documentID;
      String docTitle = docSnap.data['title'];
      DataModel wData = new DataModel(
          docId, docTitle, null);
      dowList.add(wData);
    );
  
);


 @override
 Widget build(BuildContext context) 
  return new ListView(
   children: dowList.map((DataModel item) 
    return new ListTile(
      title: new Text(item.title),
    );
  ).toList(),
);


提前感谢您的任何建议!

【问题讨论】:

【参考方案1】:

您的听众没有通知您的StatefulWidget 状态已更改。您可以通过将列表修改放入setState 来修复它:

setState(()  dowList.add(wData); );

但是,您最好使用StreamBuilder; Firestore 提供了一个与之配合使用并处理所有更新的流。因此,无论您通常将new DisplayList() 放在哪里,您都可以将其放在...

new StreamBuilder(
  stream: Firestore.instance.collection(currentCollection).snapshots,
  builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) 
    if (!snapshot.hasData) return new Text('Loading...');
    return new ListView(
      children: [... build your list items here ...],
    );
  ,
);

【讨论】:

以上是关于当另一个小部件的状态改变时重建小部件的主要内容,如果未能解决你的问题,请参考以下文章

为啥当我在其小部件中调用 Flutter 有状态小部件时,它没有改变另一个有状态小部件的状态

如何调用无状态小部件的重建?

Flutter BLoC - 状态不会触发小部件重建

三元条件没有重建我的小部件 - Flutter

Flutter 重建父小部件

为啥小部件的状态在颤动时没有改变?