1
0
mirror of https://github.com/flutter/samples.git synced 2025-11-11 07:18:15 +00:00
Files
samples/gallery/lib/demos/material/data_table_demo.dart
2020-02-05 14:11:54 -05:00

552 lines
12 KiB
Dart

// Copyright 2019 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:gallery/data/gallery_options.dart';
import 'package:gallery/l10n/gallery_localizations.dart';
import 'package:intl/intl.dart';
// BEGIN dataTableDemo
class DataTableDemo extends StatefulWidget {
@override
_DataTableDemoState createState() => _DataTableDemoState();
}
class _DataTableDemoState extends State<DataTableDemo> {
int _rowsPerPage = PaginatedDataTable.defaultRowsPerPage;
int _sortColumnIndex;
bool _sortAscending = true;
_DessertDataSource _dessertsDataSource;
@override
void didChangeDependencies() {
super.didChangeDependencies();
if (_dessertsDataSource == null) {
_dessertsDataSource = _DessertDataSource(context);
}
}
void _sort<T>(
Comparable<T> getField(_Dessert d), int columnIndex, bool ascending) {
_dessertsDataSource._sort<T>(getField, ascending);
setState(() {
_sortColumnIndex = columnIndex;
_sortAscending = ascending;
});
}
@override
Widget build(BuildContext context) {
final localizations = GalleryLocalizations.of(context);
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: Text(localizations.demoDataTableTitle),
),
body: Scrollbar(
child: ListView(
padding: const EdgeInsets.all(16),
children: [
PaginatedDataTable(
header: Text(localizations.dataTableHeader),
rowsPerPage: _rowsPerPage,
onRowsPerPageChanged: (value) {
setState(() {
_rowsPerPage = value;
});
},
sortColumnIndex: _sortColumnIndex,
sortAscending: _sortAscending,
onSelectAll: _dessertsDataSource._selectAll,
columns: [
DataColumn(
label: Text(localizations.dataTableColumnDessert),
onSort: (columnIndex, ascending) =>
_sort<String>((d) => d.name, columnIndex, ascending),
),
DataColumn(
label: Text(localizations.dataTableColumnCalories),
numeric: true,
onSort: (columnIndex, ascending) =>
_sort<num>((d) => d.calories, columnIndex, ascending),
),
DataColumn(
label: Text(localizations.dataTableColumnFat),
numeric: true,
onSort: (columnIndex, ascending) =>
_sort<num>((d) => d.fat, columnIndex, ascending),
),
DataColumn(
label: Text(localizations.dataTableColumnCarbs),
numeric: true,
onSort: (columnIndex, ascending) =>
_sort<num>((d) => d.carbs, columnIndex, ascending),
),
DataColumn(
label: Text(localizations.dataTableColumnProtein),
numeric: true,
onSort: (columnIndex, ascending) =>
_sort<num>((d) => d.protein, columnIndex, ascending),
),
DataColumn(
label: Text(localizations.dataTableColumnSodium),
numeric: true,
onSort: (columnIndex, ascending) =>
_sort<num>((d) => d.sodium, columnIndex, ascending),
),
DataColumn(
label: Text(localizations.dataTableColumnCalcium),
numeric: true,
onSort: (columnIndex, ascending) =>
_sort<num>((d) => d.calcium, columnIndex, ascending),
),
DataColumn(
label: Text(localizations.dataTableColumnIron),
numeric: true,
onSort: (columnIndex, ascending) =>
_sort<num>((d) => d.iron, columnIndex, ascending),
),
],
source: _dessertsDataSource,
),
],
),
),
);
}
}
class _Dessert {
_Dessert(this.name, this.calories, this.fat, this.carbs, this.protein,
this.sodium, this.calcium, this.iron);
final String name;
final int calories;
final double fat;
final int carbs;
final double protein;
final int sodium;
final int calcium;
final int iron;
bool selected = false;
}
class _DessertDataSource extends DataTableSource {
_DessertDataSource(this.context) {
final localizations = GalleryLocalizations.of(context);
_desserts = <_Dessert>[
_Dessert(
localizations.dataTableRowFrozenYogurt,
159,
6.0,
24,
4.0,
87,
14,
1,
),
_Dessert(
localizations.dataTableRowIceCreamSandwich,
237,
9.0,
37,
4.3,
129,
8,
1,
),
_Dessert(
localizations.dataTableRowEclair,
262,
16.0,
24,
6.0,
337,
6,
7,
),
_Dessert(
localizations.dataTableRowCupcake,
305,
3.7,
67,
4.3,
413,
3,
8,
),
_Dessert(
localizations.dataTableRowGingerbread,
356,
16.0,
49,
3.9,
327,
7,
16,
),
_Dessert(
localizations.dataTableRowJellyBean,
375,
0.0,
94,
0.0,
50,
0,
0,
),
_Dessert(
localizations.dataTableRowLollipop,
392,
0.2,
98,
0.0,
38,
0,
2,
),
_Dessert(
localizations.dataTableRowHoneycomb,
408,
3.2,
87,
6.5,
562,
0,
45,
),
_Dessert(
localizations.dataTableRowDonut,
452,
25.0,
51,
4.9,
326,
2,
22,
),
_Dessert(
localizations.dataTableRowApplePie,
518,
26.0,
65,
7.0,
54,
12,
6,
),
_Dessert(
localizations.dataTableRowWithSugar(
localizations.dataTableRowFrozenYogurt,
),
168,
6.0,
26,
4.0,
87,
14,
1,
),
_Dessert(
localizations.dataTableRowWithSugar(
localizations.dataTableRowIceCreamSandwich,
),
246,
9.0,
39,
4.3,
129,
8,
1,
),
_Dessert(
localizations.dataTableRowWithSugar(
localizations.dataTableRowEclair,
),
271,
16.0,
26,
6.0,
337,
6,
7,
),
_Dessert(
localizations.dataTableRowWithSugar(
localizations.dataTableRowCupcake,
),
314,
3.7,
69,
4.3,
413,
3,
8,
),
_Dessert(
localizations.dataTableRowWithSugar(
localizations.dataTableRowGingerbread,
),
345,
16.0,
51,
3.9,
327,
7,
16,
),
_Dessert(
localizations.dataTableRowWithSugar(
localizations.dataTableRowJellyBean,
),
364,
0.0,
96,
0.0,
50,
0,
0,
),
_Dessert(
localizations.dataTableRowWithSugar(
localizations.dataTableRowLollipop,
),
401,
0.2,
100,
0.0,
38,
0,
2,
),
_Dessert(
localizations.dataTableRowWithSugar(
localizations.dataTableRowHoneycomb,
),
417,
3.2,
89,
6.5,
562,
0,
45,
),
_Dessert(
localizations.dataTableRowWithSugar(
localizations.dataTableRowDonut,
),
461,
25.0,
53,
4.9,
326,
2,
22,
),
_Dessert(
localizations.dataTableRowWithSugar(
localizations.dataTableRowApplePie,
),
527,
26.0,
67,
7.0,
54,
12,
6,
),
_Dessert(
localizations.dataTableRowWithHoney(
localizations.dataTableRowFrozenYogurt,
),
223,
6.0,
36,
4.0,
87,
14,
1,
),
_Dessert(
localizations.dataTableRowWithHoney(
localizations.dataTableRowIceCreamSandwich,
),
301,
9.0,
49,
4.3,
129,
8,
1,
),
_Dessert(
localizations.dataTableRowWithHoney(
localizations.dataTableRowEclair,
),
326,
16.0,
36,
6.0,
337,
6,
7,
),
_Dessert(
localizations.dataTableRowWithHoney(
localizations.dataTableRowCupcake,
),
369,
3.7,
79,
4.3,
413,
3,
8,
),
_Dessert(
localizations.dataTableRowWithHoney(
localizations.dataTableRowGingerbread,
),
420,
16.0,
61,
3.9,
327,
7,
16,
),
_Dessert(
localizations.dataTableRowWithHoney(
localizations.dataTableRowJellyBean,
),
439,
0.0,
106,
0.0,
50,
0,
0,
),
_Dessert(
localizations.dataTableRowWithHoney(
localizations.dataTableRowLollipop,
),
456,
0.2,
110,
0.0,
38,
0,
2,
),
_Dessert(
localizations.dataTableRowWithHoney(
localizations.dataTableRowHoneycomb,
),
472,
3.2,
99,
6.5,
562,
0,
45,
),
_Dessert(
localizations.dataTableRowWithHoney(
localizations.dataTableRowDonut,
),
516,
25.0,
63,
4.9,
326,
2,
22,
),
_Dessert(
localizations.dataTableRowWithHoney(
localizations.dataTableRowApplePie,
),
582,
26.0,
77,
7.0,
54,
12,
6,
),
];
}
final BuildContext context;
List<_Dessert> _desserts;
void _sort<T>(Comparable<T> getField(_Dessert d), bool ascending) {
_desserts.sort((a, b) {
final Comparable<T> aValue = getField(a);
final Comparable<T> bValue = getField(b);
return ascending
? Comparable.compare(aValue, bValue)
: Comparable.compare(bValue, aValue);
});
notifyListeners();
}
int _selectedCount = 0;
@override
DataRow getRow(int index) {
final format = NumberFormat.decimalPercentPattern(
locale: GalleryOptions.of(context).locale.toString(),
decimalDigits: 0,
);
assert(index >= 0);
if (index >= _desserts.length) return null;
final _Dessert dessert = _desserts[index];
return DataRow.byIndex(
index: index,
selected: dessert.selected,
onSelectChanged: (value) {
if (dessert.selected != value) {
_selectedCount += value ? 1 : -1;
assert(_selectedCount >= 0);
dessert.selected = value;
notifyListeners();
}
},
cells: [
DataCell(Text(dessert.name)),
DataCell(Text('${dessert.calories}')),
DataCell(Text(dessert.fat.toStringAsFixed(1))),
DataCell(Text('${dessert.carbs}')),
DataCell(Text(dessert.protein.toStringAsFixed(1))),
DataCell(Text('${dessert.sodium}')),
DataCell(Text('${format.format(dessert.calcium / 100)}')),
DataCell(Text('${format.format(dessert.iron / 100)}')),
],
);
}
@override
int get rowCount => _desserts.length;
@override
bool get isRowCountApproximate => false;
@override
int get selectedRowCount => _selectedCount;
void _selectAll(bool checked) {
for (final _Dessert dessert in _desserts) {
dessert.selected = checked;
}
_selectedCount = checked ? _desserts.length : 0;
notifyListeners();
}
}
// END