从initState()更新列表时

时间:2020-03-26 08:44:28

标签: flutter

我有一个名为sqlite的{​​{1}}数据库,并且我试图在人员表中列出所有日期。我正在渲染首先初始化为空列表的日期列表。稍后,此列表中填充了people.db中调用的fetchDate()方法从数据库中检索到的数据。以下是完整代码:

initState()

我希望在卡片列表中看到所有日期(当前为2)。但这显示了一个空白页。我在import 'package:flutter/material.dart'; import 'package:sqflite/sqflite.dart'; import 'package:path/path.dart'; class ListPerson extends StatefulWidget{ @override State<StatefulWidget> createState() { return ListPersonState(); } } class ListPersonState extends State<ListPerson>{ List<Map> date = []; List<Map<String, dynamic>> temp = []; List<Map<String, dynamic>> people = []; void fetchDate() async{ var databasesPath = await getDatabasesPath(); String path = join(databasesPath, "people.db"); Database db; db = await openDatabase(path, version: 1); date = await db.rawQuery("SELECT DISTINCT date FROM people"); for (var i = 0; i < people.length; i++) { print(people[i]); } fetchPeople(date); } void fetchPeople(List<Map> date) async{ var databasesPath = await getDatabasesPath(); String path = join(databasesPath, "people.db"); Database db; db = await openDatabase(path, version: 1); for(int i=0; i< date.length; i++){ temp.addAll(await db.rawQuery("SELECT * FROM people WHERE date == '${date[i]['date']}'")) ; people.add(temp[i]); } } @override void initState(){ super.initState(); fetchDate(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Center( child: Text( "Added People", style: TextStyle( color: Colors.white, fontFamily: 'Montserrat', fontWeight: FontWeight.bold), ), ), ), body: Container( child: Column( children: <Widget>[ Expanded( child: ListView.builder( scrollDirection: Axis.vertical, shrinkWrap: true, itemCount: date.length, itemBuilder: (BuildContext context, int index){ return Card( color: Colors.white, child: Padding( padding: EdgeInsets.symmetric(vertical: 24.0, horizontal: 16.0), child: Center( child: ListTile( title: Text(date[index]['date']), ) ) ), ); }, ), ) ], ) ) ); } dropClicked() {} } 方法中添加了打印语句,以检查是否正确地从数据库中提取了数据。我不知道为什么要显示该列表。任何帮助,将不胜感激。预先谢谢你。

2 个答案:

答案 0 :(得分:1)

此列表未显示,因为您正在执行异步操作,并且在异步操作完成时已经构建了窗口小部件。

您应该在fetchPeople(date)fetchDate()之后立即致电setState。这“通知该对象的内部状态已更改的框架。”

您还应该在await调用中添加fetchPeople,以便仅在操作完成后才调用setState

所以不是

void fetchDate() async{
    //Other methods
    fetchPeople(date);
  }

您有:

void fetchDate() async{
    //Other methods
   await fetchPeople(date);
   setState((){});
  }

答案 1 :(得分:0)

正如您所检查的那样就可以了,但是我会在为您创建示例之后发布 由于您处于异步等待模式,因此UI必须执行一些任务,以便UI知道是否正在加载数据或已加载数据。我在创建的代码中进行了一些更改,分配了一个布尔值,该布尔值在UI中将显示是否正在加载数据(CircularProgressIndicator)。如果加载了数据,则将获得所需的小部件。

import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';

class ListPerson extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return ListPersonState();
  }
}

class ListPersonState extends State<ListPerson> {
  List<Map> date = [];
  List<Map<String, dynamic>> temp = [];
  List<Map<String, dynamic>> people = [];
  bool _isLoading = false;

  void fetchDate() async {
    setState(() {
      _isLoading = true;
    });
    var databasesPath = await getDatabasesPath();
    String path = join(databasesPath, "people.db");

    Database db;
    db = await openDatabase(path, version: 1);

    date = await db.rawQuery("SELECT DISTINCT date FROM people");
    for (var i = 0; i < people.length; i++) {
      print(people[i]);
    }
    fetchPeople(date);
  }

  void fetchPeople(List<Map> date) async {
    var databasesPath = await getDatabasesPath();
    String path = join(databasesPath, "people.db");

    Database db;
    db = await openDatabase(path, version: 1);

    for (int i = 0; i < date.length; i++) {
      temp.addAll(await db
          .rawQuery("SELECT * FROM people WHERE date == '${date[i]['date']}'"));
      people.add(temp[i]);
    }
    setState(() {
      _isLoading = false;
    });
  }

  @override
  void initState() {
    super.initState();
    fetchDate();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Center(
            child: Text(
              "Added People",
              style: TextStyle(
                  color: Colors.white,
                  fontFamily: 'Montserrat',
                  fontWeight: FontWeight.bold),
            ),
          ),
        ),
        body: _isLoading
            ? Center(
              // this will show the laoding untill you load the data
                child: CircularProgressIndicator(),
              )
            : Container(
                child: Column(
                children: <Widget>[
                  Expanded(
                    child: ListView.builder(
                      scrollDirection: Axis.vertical,
                      shrinkWrap: true,
                      itemCount: date.length,
                      itemBuilder: (BuildContext context, int index) {
                        return Card(
                          color: Colors.white,
                          child: Padding(
                              padding: EdgeInsets.symmetric(
                                  vertical: 24.0, horizontal: 16.0),
                              child: Center(
                                  child: ListTile(
                                title: Text(date[index]['date']),
                              ))),
                        );
                      },
                    ),
                  )
                ],
              )));
  }

  dropClicked() {}
}