Итак, я (пытаюсь) создать DataTable для динамического отображения группы пакетов (таких как пакеты Amazon или UPS) на основе данных Firestore. Сложность заключается в следующем: мои данные хранятся в нескольких коллекциях в базе данных, в «очереди», «в доме» и «учениках».
Я создал версию того, что я хочу, используя ListView.builder и ListViewTiles. В настоящее время он работает отлично, отображая новые плитки по мере добавления новых данных в очередь. Вместо использования ListView я хотел бы отобразить все данные в таблице (DataTable); однако у меня возникли проблемы с тем, чтобы уместить то, что у меня уже есть (FutureBuilders и StreamBuilders), таким образом, чтобы это работало с DataTable.
У меня также есть заполнитель DataTable, который отображает несколько фиктивных пакетов из предопределенных список точно так, как я хочу.
Я провел исследование использования провайдера для предоставления списка перестройки для виджета DataTable ... Но я не могу соединить точки при попытке чтения из нескольких коллекций одновременно.
Вот код для моего ListView ...
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
class QueueDisplay extends StatefulWidget {
@override
_QueueDisplayState createState() => _QueueDisplayState();
}
class _QueueDisplayState extends State<QueueDisplay> {
@override
Widget build(BuildContext context) {
return Container(
child: StreamBuilder(
stream: Firestore.instance.collection('queue').snapshots(),
builder:(context, snapshot){
if (!snapshot.hasData){
return (Center(child: CircularProgressIndicator()));
} else {
return ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
DocumentSnapshot queueDoc = snapshot.data.documents[index];
return Column(
children: <Widget>[
FutureBuilder(
future: Firestore.instance.collection('students').document('${queueDoc.data['owner']}').get(),
builder: (BuildContext context, AsyncSnapshot studentSnap) {
return FutureBuilder(
future: Firestore.instance.collection('inhouse').where('owner', isEqualTo: queueDoc.data['owner']).getDocuments(),
builder: (BuildContext context, AsyncSnapshot packSnap) {
if (packSnap.hasData){
if(packSnap.data!=null){
return ListTile(
title: Row(
children: <Widget>[
Text('${queueDoc.data['owner']}' + ' '),
Text('${studentSnap.data['name']}' + ' '),
Text('${packSnap.data.documents[0].documentID}'),
],
)
);
}
} else {
return Center(child: CircularProgressIndicator());
}
return Center(child: CircularProgressIndicator());
},
);
},
)
],
);
},
);
}
},
),
);
}
}
Функционирование Снимок экрана ListView
А вот код для заполнителя DataTable ...
class QueueTable extends StatefulWidget {
@override
_QueueTableState createState() => _QueueTableState();
}
class _QueueTableState extends State<QueueTable> {
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Container(
//color: Colors.grey[200],
child: DataTable(
// Table Displaying Queued Packages
columnSpacing: 8,
columns: [
DataColumn(label: Text("Name"),numeric: false, onSort: (i, b) {}),
DataColumn(label: Text("Location"),numeric: false, onSort: (i, b) {}),
DataColumn(label: Text("Tracking"),numeric: false, onSort: (i, b) {}),
DataColumn(label: Text("Carrier"),numeric: false, onSort: (i, b) {}),
DataColumn(label: Text("Notes"),numeric: false, onSort: (i, b) {}),
DataColumn(label: Text("Received"),numeric: false, onSort: (i, b) {}),
],
rows: packages.map((package) => DataRow(
onSelectChanged: (b) {},
cells: [
DataCell(Text(package.owner.name), onTap: (){}),
DataCell(Text(package.location), onTap: (){}),
DataCell(Text(package.tracking)),
DataCell(Text(package.carrier)),
DataCell(Text(package.notes), onTap: (){}),
DataCell(Text(package.rDate)),
])).toList()
),
),
);
}
}
Student adam =
Student('0000004028', 'Adam G', 'adamg@email.net');
var packages = [
Package(adam, 'Large', 'USPS', '1/15/2020', '123456', 'Great Dude!'),
Package(adam, 'Small', 'UPS', '1/16/2020', '1234567', 'Great Guy!'),
Package(adam, 'Medium', 'FedEx', '1/18/2020', '12345678', 'Great Bro!'),
Package(adam, 'Floor', 'Amazon', '1/5/2020', '123456789', 'Great Person!'),
];
Скриншот заполнителя DataTable
Оба предоставленных фрагмента кода должны работать нормально; Я просто не могу объединить их в рабочую динамику c DataTable ...
Есть предложения? Спасибо!
Обновление:
Итак, вот моя ближайшая попытка до сих пор ...
Я создал поток List и использовал StreamProvider для предоставить поток виджету, создающему DataTable.
database.dart
Поставщик, который возвращает только нулевые пакеты
It кажется, что будет работать; если бы только я мог получить _queueListFromSnapshot, чтобы вернуть правильное значение для пакета p. Из-за вложенных операторов Future.then () {} я пока не могу понять, как вернуть правильное значение. (Показано в комментариях database.dart)
Обновление 2:
Вот чуть лучше попробуйте с использованием async / await. Это требует, чтобы я изменил тип возвращаемого значения функции, что вызывает несоответствие дальше, потому что я все еще хочу вернуть заполненный список в StreamProvider ... правильно?