Peut-on définir Flutter PaginatedDataTable rowsPerPage sur un nombre non divisible par 10?
MISE À JOUR
Les données utilisées par FutureBuilder sont extraites d'un serveur local. Au début, la liste contient 3 éléments, ce qui entraîne la création de DataRows vides.
Mon problème
Ce que j'ai essayé
CODE EXEMPLE
import 'package:flutter/material.dart';
import 'package:nvip/models/vaccination_center.dart';
class CentersTableDataSource extends DataTableSource {
final List<VaccineCenter> _centers;
int _rowsSelectedCount = 0;
CentersTableDataSource(this._centers);
@override
DataRow getRow(int index) {
assert(index >= 0);
if (index >= _centers.length) return null;
final VaccineCenter center = _centers[index];
return DataRow.byIndex(
index: index,
selected: center.isSelected,
onSelectChanged: (selected) {
if (center.isSelected != selected) {
_rowsSelectedCount += selected ? 1 : -1;
center.isSelected = selected;
notifyListeners();
}
},
cells: <DataCell>[
DataCell(Text("${index + 1}")),
DataCell(Text(center.name)),
],
);
}
@override
bool get isRowCountApproximate => false;
@override
int get rowCount => _centers.length;
@override
int get selectedRowCount => _rowsSelectedCount;
void sort<T extends Object>(
Comparable<T> getField(VaccineCenter d), bool isAscending) {
_centers.sort((a, b) {
if (isAscending) {
final VaccineCenter c = a;
a = b;
b = c;
}
final Comparable<T> aValue = getField(a);
final Comparable<T> bValue = getField(b);
return Comparable.compare(aValue, bValue);
});
notifyListeners();
}
void selectAll(bool isAllChecked) {
_centers.forEach((center) => center.isSelected = isAllChecked);
_rowsSelectedCount = isAllChecked ? _centers.length : 0;
notifyListeners();
}
}
JOURNAL DES ERREURS
I/flutter ( 8474): âââ¡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ I/flutter ( 8474): The following assertion was thrown building FutureBuilder<List<VaccineCenter>>(dirty, state: I/flutter ( 8474): _FutureBuilderState<List<VaccineCenter>>#92379): I/flutter ( 8474): 'package:flutter/src/material/paginated_data_table.dart': Failed assertion: line 87 pos 19: I/flutter ( 8474): 'availableRowsPerPage != null && availableRowsPerPage.contains(rowsPerPage)': is not true. I/flutter ( 8474): I/flutter ( 8474): Either the assertion indicates an error in the framework itself, or we should provide substantially I/flutter ( 8474): more information in this error message to help you determine and fix the underlying cause. I/flutter ( 8474): In either case, please report this assertion by filing a bug on GitHub: I/flutter ( 8474): https://github.com/flutter/flutter/issues/new?template=BUG.md I/flutter ( 8474): I/flutter ( 8474): When the exception was thrown, this was the stack: I/flutter ( 8474): #2 new PaginatedDataTable.<anonymous closure> (package:flutter/src/material/paginated_data_table.dart:87:19) I/flutter ( 8474): #3 new PaginatedDataTable (package:flutter/src/material/paginated_data_table.dart:89:9) I/flutter ( 8474): #4 __CentersScreenBodyState.build.<anonymous closure> (package:nvip/scenes/vaccination_centers/screen_center_table.dart:86:26) I/flutter ( 8474): #5 _FutureBuilderState.build (package:flutter/src/widgets/async.dart) I/flutter ( 8474): #6 StatefulElement.build (package:flutter/src/widgets/framework.dart:3809:27) I/flutter ( 8474): #7 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3721:15) I/flutter ( 8474): #8 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5) I/flutter ( 8474): #9 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2286:33) I/flutter ( 8474): #10 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:676:20) I/flutter ( 8474): #11 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:219:5) I/flutter ( 8474): #12 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:990:15) I/flutter ( 8474): #13 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:930:9) I/flutter ( 8474): #14 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:842:5) I/flutter ( 8474): #15 _invoke (dart:ui/hooks.dart:154:13) I/flutter ( 8474): #16 _drawFrame (dart:ui/hooks.dart:143:3) I/flutter ( 8474): (elided 2 frames from class _AssertionError) I/flutter ( 8474): ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
5 Réponses :
import 'package:flutter/material.dart';
class DemoTable extends StatelessWidget {
@override
Widget build(BuildContext context) {
return _DemoTableBody();
}
}
class _DemoTableBody extends StatefulWidget {
@override
__DemoTableBodyState createState() => __DemoTableBodyState();
}
class __DemoTableBodyState extends State<_DemoTableBody> {
int _rowsPerPage = PaginatedDataTable.defaultRowsPerPage;
// A Variable to hold the length of table based on the condition of comparing the actual data length with the PaginatedDataTable.defaultRowsPerPage
int _rowsPerPage1 = PaginatedDataTable.defaultRowsPerPage;
@override
Widget build(BuildContext context) {
//Obtain the data to be displayed from the Derived DataTableSource
var dts = DTS();
// dts.rowcount provides the actual data length, ForInstance, If we have 7 data stored in the DataTableSource Object, then we will get 12 as dts.rowCount
var tableItemsCount = dts.rowCount;
// PaginatedDataTable.defaultRowsPerPage provides value as 10
var defaultRowsPerPage = PaginatedDataTable.defaultRowsPerPage;
// We are checking whether tablesItemCount is less than the defaultRowsPerPage which means we are actually checking the length of the data in DataTableSource with default PaginatedDataTable.defaultRowsPerPage i.e, 10
var isRowCountLessDefaultRowsPerPage = tableItemsCount < defaultRowsPerPage;
// Assigning rowsPerPage as 10 or acutal length of our data in stored in the DataTableSource Object
_rowsPerPage =
isRowCountLessDefaultRowsPerPage ? tableItemsCount : defaultRowsPerPage;
return Scaffold(
appBar: AppBar(
title: Text("Demo Paginated Table"),
),
body: SingleChildScrollView(
child: PaginatedDataTable(
header: Text('data with 7 rows per page'),
// comparing the actual data length with the PaginatedDataTable.defaultRowsPerPage and then assigning it to _rowPerPage1 variable which then set using the setsState()
onRowsPerPageChanged: isRowCountLessDefaultRowsPerPage // The source of problem!
? null
: (rowCount) {
setState(() {
_rowsPerPage1 = rowCount;
});
},
columns: <DataColumn>[
DataColumn(label: Text('row')),
DataColumn(label: Text('name')),
],
source: dts,
//Set Value for rowsPerPage based on comparing the actual data length with the PaginatedDataTable.defaultRowsPerPage
rowsPerPage:
isRowCountLessDefaultRowsPerPage ? _rowsPerPage : _rowsPerPage1,
),
),
);
}
}
class DTS extends DataTableSource {
@override
DataRow getRow(int index) {
return DataRow.byIndex(
index: index,
cells: [
DataCell(Text('row #$index')),
DataCell(Text('name #$index')),
],
);
}
@override
int get rowCount => 9; // Manipulate this to which ever value you wish
@override
bool get isRowCountApproximate => false;
@override
int get selectedRowCount => 0;
}
Cette erreur est causée par les valeurs fournies par flutter. rowsPerPage ne peut être que 10, 20, 50 et 100.
source de l'instantané PaginatedDataTable
Ceci est spécifié dans la source PaginationDataTable .
J'ai réalisé que. C'est pourquoi j'ai décidé de proposer une solution «personnalisée» car la réponse que j'ai donnée ci-dessus m'a aidé à résoudre mon problème
Supposons que vous ayez une méthode qui récupère les données d'un serveur distant ou localement et renvoie une liste d'objets comme celui-ci:
onRowsPerPageChanged: (fetchedDataObj.length < PaginatedDataTable.defaultRowsPerPage) ? null : (r) {
// setState(() {
// _rowsPerPage = r;
// });
},
),
dans le jeu de widgets PaginatedDataTable :
rowsPerPage: fetchedDataObj.length,
et
List<Map<String, String>> fetchedDataObj = [
{
"name": "Rami",
"email": "dummyemail01@gmail.com"
},
{
"name": "Kara",
"email": "dummyemail02@gmail.com"
},
{
"name": "Lina",
"email": "dummyemail03@almakana.com"
}
];
J'espère que cela vous aidera. Merci
Je doute que cela conduise à une table paginée
Cette méthode ne fonctionne pas. En fait, il va à l'encontre de l'objectif de paginatedDataTable car il tente de définir les lignes par page sur l'ensemble de données.
Je laisse ça au prochain car je viens de me battre contre ça récemment.
Pour le moment, il semble que PaginatedDataTable contient quelques bugs ... c'est l'un d'entre eux. Si le nombre d'éléments de données n'est pas exactement égal au nombre sélectionné de lignes par page, le widget PaginatedDataTable place des 'lignes de remplissage'
Jusqu'à ce que cela soit corrigé, je vous recommande de prendre le widget PaginatedDataTable le fichier paginated_data_table.dart et le mettre dans votre projet afin de le personnaliser. (vous devrez remplacer toutes les dépendances qui ne sont pas trouvées par un simple import 'package: flutter / material.dart';
Afin de limiter le nombre des lignes vues, ajoutez les lignes avec //
Text(
localizations.pageRowsInfoTitle(
_firstRowIndex + 1,
(_firstRowIndex + widget.rowsPerPage <= _rowCount)?_firstRowIndex + widget.rowsPerPage:_rowCount,
_rowCount,
_rowCountApproximate,
),
),
De plus, le nombre de pages sera maintenant désactivé, donc vous ' Vous devrez changer cette section ci-dessous afin d'ajouter l'opérateur ternaire pour changer le décompte final:
List<DataRow> _getRows(int firstRowIndex, int rowsPerPage) {
final List<DataRow> result = <DataRow>[];
final int nextPageFirstRowIndex = firstRowIndex + rowsPerPage;
bool haveProgressIndicator = false;
for (int index = firstRowIndex; index < nextPageFirstRowIndex; index += 1) {
if (index < _rowCount) { // <---
// This stops "overflow" rows from appearing on the last page.
DataRow row;
if (index < _rowCount || _rowCountApproximate) {
row = _rows.putIfAbsent(index, () => widget.source.getRow(index));
if (row == null && !haveProgressIndicator) {
row ??= _getProgressIndicatorRowFor(index);
haveProgressIndicator = true;
}
}
row ??= _getBlankRowFor(index);
result.add(row);
} // <---
}
return result;
}
rowsPerPage et availableRowsPerPage doivent être définis ensemble.
Par exemple:
_rowsPerPage = 5;
recalculer _rowsPerPage dans la méthode de construction:
PaginatedDataTable(
header: Text("dataTableHeader"),
rowsPerPage: _rowsPerPage,
availableRowsPerPage: <int>[_rowsPerPage, _rowsPerPage * 2, _rowsPerPage * 5, _rowsPerPage * 10],......
puis ajoutez rowsPerPage , availableRowsPerPage à la PaginatedDataTable dans _buildCollectivePanel()
@override
Widget build(BuildContext context) {
_rowsPerPage = widget.items.length > 5 ? 5 : widget.items.length;
return _buildCollectivePanel();
}
oui, il peut être défini sur n'importe quelle valeur
J'ai essayé d'utiliser une valeur différente d'un nombre divisible par 10 et cela ne fonctionne pas. Je mettrai à jour la question avec l'exemple de code et le journal des erreurs.
@pskink merci d'avoir répondu. Cela ne fonctionne toujours pas. Consultez mon exemple de code pour le DataTableSource après (mise à jour 2)
@pskink votre code fonctionnait bien jusqu'à ce que j'ajoute un onRowsPerPageChanged pour la PaginationDataTable. Je me rends compte que c'est ce qui a causé l'erreur.
@pskink le problème était que je ne voulais pas que les lignes vides soient affichées sur le tableau (en particulier dans la première page). Cela s'est produit lorsque la liste des éléments à afficher dans le tableau était inférieure à defaultRowsPerPage (10). Donc, je pensais qu'initialiser la taille rowsPerPage à la longueur de la liste si la taille de la liste est inférieure à la valeur defaultRowsPerPage résoudrait le problème, mais ce n'est pas le cas jusqu'à ce que je découvre que la logique était bonne, sauf qu'elle ne fonctionnait pas bien avec onRowsPerPageChanged de le PaginatedDataTable. Veuillez consulter ma réponse pour en savoir plus sur la source du problème.