如何在floatactionbutton上重建小部件?

时间:2019-07-26 05:34:38

标签: flutter google-cloud-firestore

我正在尝试从Firebase云Firestore提取新数据,并在onPress的浮动操作按钮上重建窗口小部件。我不确定如何重建整个小部件。试图从onPressed和setState()调用getList,但仍然没有更新窗口小部件nameList的更新。

class MyList extends StatefulWidget {
  static const String id = 'test';
  @override
  _MyListState createState() => _MyListState();
}

class _MyListState extends State<MyList> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('TEST'),),
      body: MainList(),
      floatingActionButton: FloatingActionButton(
          child: Icon(Icons.refresh),
          backgroundColor: Colors.teal,
          onPressed: () {
          }),
    );
  }
}

class MainList extends StatefulWidget {
  @override
  _MainListState createState() => _MainListState();
}

class _MainListState extends State<MainList> {
  List<Test> nameList = [];
  @override
  void initState() {
    super.initState();
    getList();
  }

  getList() async {
    final _name = await 
Firestore.instance.collection('test').getDocuments();
    nameList.clear();
    for (var name in _name.documents) {
      Test addName = new Test(
        name.data['name'],
      );
      nameList.add(addName);
      setState(() {});
    }
  }

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
        itemCount: nameList.length,
        itemBuilder: (BuildContext context, int index) {
          return Container(
            child: Text(nameList[index].name),
          );
        });
  }
}

2 个答案:

答案 0 :(得分:0)

仅调用setState()是不够的。您必须告诉Dart您将要设置的内容。示例代码:

setState ( ()=> nameList = _fetchedList ) ;

在上面的代码中,变量名称列表在 setState()中分配。

在您的代码中,您有两个选择。 选项1:

setState(() {
  nameList.clear();
  for (var name in _name.documents) {
      Test addName = new Test(
        name.data['name'],
      );
      nameList.add(addName);
    }      
});

或者选择2(更好的方法),使用for循环将数据添加到另一个列表中,并使用setState和以下一行:

List<Test> _fetchedList ;

  for (var name in _name.documents) {
      Test addName = new Test(
        name.data['name'],
      );
      _fetchedList.add(addName);
    }  

setState( ()=> nameList = _fetchedList ) ;

答案 1 :(得分:0)

一旦创建了窗口小部件,initState就不会再次调用。因此,您的列表视图仍在反映旧数据。

您可以在getListonPressed,然后更新您的nameList。然后,您可以将此nameList传递给MainList

class MyList extends StatefulWidget {
  static const String id = 'test';
  @override
  _MyListState createState() => _MyListState();
}

class _MyListState extends State<MyList> {
 List<Test> nameList = [];  

 getList() async {
    final _name = await 
Firestore.instance.collection('test').getDocuments();
    nameList.clear();
    for (var name in _name.documents) {
      Test addName = new Test(
        name.data['name'],
      );
      nameList.add(addName);
      setState(() {});
    }
  }  

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('TEST'),),
      body: MainList(nameList: nameList),
      floatingActionButton: FloatingActionButton(
          child: Icon(Icons.refresh),
          backgroundColor: Colors.teal,
          onPressed: () {
             getList();
          }),
    );
  }
}

您的MainList小部件将如下所示:

class MainList extends StatefulWidget {
  final List nameList;

  MainList({this.nameList});

  @override
  _MainListState createState() => _MainListState();
}

class _MainListState extends State<MainList> {

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
        itemCount: nameList.length,
        itemBuilder: (BuildContext context, int index) {
          return Container(
            child: Text(nameList[index].name),
          );
        });
  }
}