提问人:ben 提问时间:3/18/2023 最后编辑:ben 更新时间:3/21/2023 访问量:98
Flutter 可扩展分组列表视图
Flutter Expandable Grouped Listview
问:
我有一个现有的,我想转换(或替换为)一个小部件。我的数据源来自 Firebase Firestore。GroupedListView
Expandable
在所有“试图弄清楚”的情况下,我的代码都非常混乱,所以我会把它作为最后的手段,以保持帖子尽可能干净。它看起来像这样:
List<String> _headers = [];
List<Map<String, dynamic>> = [];
List finalList = [];
await FirebaseFirestore.instance.collection('collection').get().then((snapshot){
for(final document in snapshot.docs){
if(!_headers.contains(document.data()['headerDate'])){
_headers.add(document.data()['headerDate']);
}
}
});
await FirebaseFirestore.instance.collection('collection').get().then((snapshot){
for(headerItem in _headers){
List<Map<String, dynamic>> tempData = [];
for(final document in snapshot.docs){
if(document.data()['headerDate'] == headerItem){
tempData.add([{'name': document.data()['name'], 'idNo': document.data()['idNo'], document.data()['amount']});
}
}
finalList.add([headerItem, tempData]);
}
});
在此之后,我几乎被困住了,不知道如何映射每个数据下的数据以显示在可扩展的组中。headerItem
遵循这种结构是否安全,或者我是否有可能得到无序的结果?另外,有没有一种更简洁的方法来编写我目前拥有的代码?
感谢您对此的帮助!
编辑:
我仍然无法做到这一点。这是我对它的理解。
我的模型代码:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:collection/collection.dart';
class AttendanceData {
static final _collection =
FirebaseFirestore.instance.collection('attendance2').withConverter(
fromFirestore: _fromFirestore,
toFirestore: _toFirestore,
);
final String headerDate;
final String tagName;
final String tagId;
final String workerType;
final String teamName;
final bool clockedIn;
final String timeIn;
final String timeOut;
final String employeeId;
AttendanceData(
{required this.tagName,
required this.tagId,
required this.workerType,
required this.teamName,
required this.clockedIn,
required this.timeIn,
required this.timeOut,
required this.employeeId,
required this.headerDate});
static AttendanceData _fromFirestore(
DocumentSnapshot<Map<String, dynamic>> snapshot,
SnapshotOptions? options,
) =>
AttendanceData.fromSnapshot(snapshot);
static Map<String, dynamic> _toFirestore(
AttendanceData assignment,
SetOptions? options,
) =>
assignment.toFirestore();
factory AttendanceData.fromSnapshot(
DocumentSnapshot<Map<String, dynamic>> snapshot,
) {
final staffData = snapshot.data();
return AttendanceData(
headerDate: staffData?['headerDate'],
tagName: staffData?['tag_name'],
tagId: staffData?['tag_id'],
workerType: staffData?['worker_type'],
teamName: staffData?['team_name'],
clockedIn: staffData?['clockedIn'],
timeIn: staffData?['timeIn'],
timeOut: staffData?['timeOut'],
employeeId: staffData?['employeeId'],
);
}
Map<String, dynamic> toFirestore() {
return {
'headerDate': headerDate,
'tag_name': tagName,
'tag_id': tagId,
'worker_type': workerType,
'team_name': teamName,
'clockedIn': clockedIn,
'timeIn': timeIn,
'timeOut': timeOut,
'employeeId': employeeId,
};
}
static Stream<QuerySnapshot<AttendanceData>> snapshots() =>
_collection.snapshots();
Map<String, List<dynamic>> groupByHeaderDate(collectionData) {
return groupBy(collectionData, (collection) => collection.headerDate);
}
}
然后在StreamBuilder
StreamBuilder(
stream: AttendanceData.snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
return staffData.keys.map((collection) =>
ExpansionTile(
title: collection.headerDate,
subtitle: collection.tagName
)).toList();
答:
1赞
Lodewyk Roux
3/18/2023
#1
你可以看看这个: 如何在 Flutter 中使用 Firestore 和 Converter
它将为您提供有关如何使用数据构造适当类的想法。
我要做的是首先使用转换器获取数据,然后方便地将其转换为对象供您使用。
然后,我将使用 groupBy 方法按特定属性对数据进行分组(您可以将此方法包含在对象类中)。
然后,我会将此数据映射到所需的可扩展项中。
import 'package:collection/collection.dart';
class Collection {
static final _collection =
FirebaseFirestore.instance.collection('collection').withConverter(
fromFirestore: _fromFirestore,
toFirestore: _toFirestore,
);
final Date headerDate;
final String name;
etc...
Collection({
required this.headerDate,
required this.name,
etc...
})
static Collection _fromFirestore(
DocumentSnapshot<Map<String, dynamic>> snapshot,
SnapshotOptions? options,
) =>
Collection.fromSnapshot(snapshot);
static Map<String, dynamic> _toFirestore(
Collection assignment,
SetOptions? options,
) =>
assignment.toFirestore();
factory Collection.fromSnapshot(
DocumentSnapshot<Map<String, dynamic>> snapshot,
) {
final data = snapshot.data();
return Collection(
headerDate: DateTime.parse(data['headerDate']),
name: data['name'],
etc...
);
}
Map<String, dynamic> toFirestore() {
return {
'headerDate': headerDate.toIso8601String,
'name': name,
etc...,
};
}
Map<Date,List<dynamic>> groupByHeaderDate(Collection collectionData) {
return groupBy(collectionData, (Collection collection) => collection.headerDate);
}
}
然后,您可以简单地使用groupByHeaderDate中的数据,如下所示:
data.keys.map((collection) => Expandable(..properties..)).toList()
评论
0赞
ben
3/19/2023
谢谢Lodewyk。这看起来好像会起作用,只是几个问题。1,我收到一个未在类中使用的警告。 2,添加时会抛出错误“未定义的名称'数据'”。我将您的示例放在一个类中,并将 data 部分放在 .我这样做是对的还是在这里没有达到目标?3,我还收到错误“'groupBy'未为'Collection'类型定义”。_collection
data.keys...
StreamBuilder
0赞
Lodewyk Roux
3/19/2023
您可以将其添加到模型中: 然后,您可以使用以下信息收听页面上的快照 可展开: stackoverflow.com/questions/50471309/... .至于 groupBy,请确保在 pubspec.yaml 中有 collection 作为依赖项,并确保导入集合,就像我的代码示例顶部一样。static Stream<QuerySnapshot<Collection>> snapshots() => _collection.snapshots();
评论