Flutter 可扩展分组列表视图

Flutter Expandable Grouped Listview

提问人:ben 提问时间:3/18/2023 最后编辑:ben 更新时间:3/21/2023 访问量:98

问:

我有一个现有的,我想转换(或替换为)一个小部件。我的数据源来自 Firebase Firestore。GroupedListViewExpandable

在所有“试图弄清楚”的情况下,我的代码都非常混乱,所以我会把它作为最后的手段,以保持帖子尽可能干净。它看起来像这样:

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();
flutter google-cloud-firestore flutter-listview 可扩展分组 列表

评论


答:

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'类型定义”。_collectiondata.keys...StreamBuilder
0赞 Lodewyk Roux 3/19/2023
您可以将其添加到模型中: 然后,您可以使用以下信息收听页面上的快照 可展开: stackoverflow.com/questions/50471309/... .至于 groupBy,请确保在 pubspec.yaml 中有 collection 作为依赖项,并确保导入集合,就像我的代码示例顶部一样。static Stream<QuerySnapshot<Collection>> snapshots() => _collection.snapshots();