我有一个名为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() {}
}
方法中添加了打印语句,以检查是否正确地从数据库中提取了数据。我不知道为什么要显示该列表。任何帮助,将不胜感激。预先谢谢你。
答案 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() {}
}