Flutter 如何在Listview生成器中使用async/await
我的sqflite数据库中有一个表,其中包含各个用户的呼叫历史记录。现在在flutter中的调用历史页面上,我显示了完整的历史数据,这些数据是从sqflite中获取的,到目前为止,工作正常。但现在我想检查我的历史记录列表中的号码是否存在联系人。如果是,那么我想在列表中显示他们的联系人姓名和头像。否则我只想显示数字。这是我的密码:Flutter 如何在Listview生成器中使用async/await,flutter,Flutter,我的sqflite数据库中有一个表,其中包含各个用户的呼叫历史记录。现在在flutter中的调用历史页面上,我显示了完整的历史数据,这些数据是从sqflite中获取的,到目前为止,工作正常。但现在我想检查我的历史记录列表中的号码是否存在联系人。如果是,那么我想在列表中显示他们的联系人姓名和头像。否则我只想显示数字。这是我的密码: List<Map<String, dynamic>> ok = await DatabaseHelper.instance.getAllLogs
List<Map<String, dynamic>> ok =
await DatabaseHelper.instance.getAllLogs(argv);
setState(() {
queryRows = ok;
});
var historyRecords = List<HistoryRecord>.from(queryRows.map((row) => HistoryRecord.fromJson(row)));
FutureBuilder<List<HistoryRecord>>(
future: _checkContact(historyRecords),
builder: (context, snapshot) {
return ListView.builder(
itemCount: historyRecords.length,
itemBuilder: (context, index) {
print(historyRecords[index]);
},
);
},
)
Future<List<HistoryRecord>> _checkContact(List<HistoryRecord> rec)async
{
for(int i=0;i<rec.length;i++) {
var conhere=await
ContactsService.getContactsForPhone(rec[i].callHistoryNumber);
//how should i map iterable contact list to Historyrecord
}
}
列表确定=
等待DatabaseHelper.instance.getAllLogs(argv);
设置状态(){
queryRows=ok;
});
var historyRecords=List.from(queryRows.map((行)=>HistoryRecord.fromJson(行));
未来建设者(
未来:_检查联系人(历史记录),
生成器:(上下文,快照){
返回ListView.builder(
itemCount:historyRecords.length,
itemBuilder:(上下文,索引){
打印(历史记录[索引]);
},
);
},
)
未来检查联系人(列表记录)异步
{
对于(int i=0;i要在UI中调用异步调用,您可以使用FutureBuilder。您可以对列表中的每个项目运行检查,如下所示:
FutureBuilder(
initialData:false,//您可以在生成器中设置初始数据或检查snapshot.hasData
future:_checkRecordInContact(queryRow),//对单个queryRow运行检查
生成器:(上下文,快照){
if(snapshot.data){//snapshot.data是从上述异步函数返回的内容
//正确:在此处返回带有姓名和头像的UI元素,以获取联系人中的号码
}否则{
//False:返回没有名称和化身的UI元素
}
},
);
但是我不推荐这种方法,因为异步调用太多会减慢应用程序的速度。我建议首先在queryRows
中运行所有项目的检查,然后将其发送到UI
首先,您应该使用对象来表示历史记录,而不是映射,以避免在处理数据时出现错误。假设我们有一个HistoryRecord
对象列表,从queryRows
解析。我们将此列表称为historyRecords
var historyRecords=List.from(queryRows.map((行)=>HistoryRecord.fromJson(行));
每个对象都应该有一个布尔属性fromContact
,以检查它是否在Contacts中。然后我们可以执行以下操作:
Widget buildListView(历史记录){
回归未来建设者(
future:_checkContact(historyRecords),//在这里,您可以对所有queryRows项运行检查,并为每个项分配fromContact属性
生成器:(上下文,快照){
ListView.builder(
itemCount:historyRecords.length,
itemBuilder:(上下文,索引){
if(historyRecords[index].fromContact){//检查记录是否在Contacts中
//正确:在此处返回带有名称和头像的UI元素
}否则{
//False:返回没有名称和化身的UI元素
}
},
);
},
);
}
然后,您可以使用HistoryRecord和function的以下属性检查联系人:
类历史记录{
bool-fromContact;
UINT8列表化身;
字符串名;
//……其他财产
历史记录({this.fromContact,this.avatar,this.name});
}
未来检查联系人(列表记录)异步{
对于(int i=0;i
要在UI中调用异步调用,您可以使用FutureBuilder。您可以对列表中的每个项目运行检查,如下所示:
FutureBuilder(
initialData:false,//您可以在生成器中设置初始数据或检查snapshot.hasData
future:_checkRecordInContact(queryRow),//对单个queryRow运行检查
生成器:(上下文,快照){
if(snapshot.data){//snapshot.data是从上述异步函数返回的内容
//正确:在此处返回带有姓名和头像的UI元素,以获取联系人中的号码
}否则{
//False:返回没有名称和化身的UI元素
}
},
);
但是我不推荐这种方法,因为异步调用太多会减慢应用程序的速度。我建议首先在queryRows
中运行所有项目的检查,然后将其发送到UI
首先,您应该使用对象来表示历史记录,而不是映射,以避免在处理数据时出现错误。假设我们有一个HistoryRecord
对象列表,从queryRows
解析。我们将此列表称为historyRecords
var historyRecords=List.from(queryRows.map((行)=>HistoryRecord.fromJson(行));
每个对象都应该有一个布尔属性fromContact
,以检查它是否在Contacts中。然后我们可以执行以下操作:
Widget buildListView(历史记录){
回归未来建设者(
future:_checkContact(historyRecords),//在这里,您可以对所有queryRows项运行检查,并为每个项分配fromContact属性
生成器:(上下文,快照){
ListView.builder(
itemCount:historyRecords.length,
itemBuilder:(上下文,索引){
if(historyRecords[index].fromContact){//检查记录是否在Contacts中
//正确:在此处返回带有名称和头像的UI元素
}否则{
//False:返回没有名称和化身的UI元素
}
},
);
},
);
}
然后,您可以使用HistoryRecord和function的以下属性检查联系人:
类历史记录
ListView.builder(
itemCount: history.length,
itemBuilder: (context, index) {
FutureBuilder(
future: checkContactExists(history[0]),
builder: (context, snap){
if(snap.hasData){
if(snap.data = true){
return PersonContact();
}else{
return JustNumber();
}
}
return Loading();
}
)
},
);