// 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 { int _rowsPerPage = PaginatedDataTable.defaultRowsPerPage; int _sortColumnIndex; bool _sortAscending = true; _DessertDataSource _dessertsDataSource; @override void didChangeDependencies() { super.didChangeDependencies(); if (_dessertsDataSource == null) { _dessertsDataSource = _DessertDataSource(context); } } void _sort( Comparable getField(_Dessert d), int columnIndex, bool ascending) { _dessertsDataSource._sort(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((d) => d.name, columnIndex, ascending), ), DataColumn( label: Text(localizations.dataTableColumnCalories), numeric: true, onSort: (columnIndex, ascending) => _sort((d) => d.calories, columnIndex, ascending), ), DataColumn( label: Text(localizations.dataTableColumnFat), numeric: true, onSort: (columnIndex, ascending) => _sort((d) => d.fat, columnIndex, ascending), ), DataColumn( label: Text(localizations.dataTableColumnCarbs), numeric: true, onSort: (columnIndex, ascending) => _sort((d) => d.carbs, columnIndex, ascending), ), DataColumn( label: Text(localizations.dataTableColumnProtein), numeric: true, onSort: (columnIndex, ascending) => _sort((d) => d.protein, columnIndex, ascending), ), DataColumn( label: Text(localizations.dataTableColumnSodium), numeric: true, onSort: (columnIndex, ascending) => _sort((d) => d.sodium, columnIndex, ascending), ), DataColumn( label: Text(localizations.dataTableColumnCalcium), numeric: true, onSort: (columnIndex, ascending) => _sort((d) => d.calcium, columnIndex, ascending), ), DataColumn( label: Text(localizations.dataTableColumnIron), numeric: true, onSort: (columnIndex, ascending) => _sort((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(Comparable getField(_Dessert d), bool ascending) { _desserts.sort((a, b) { final Comparable aValue = getField(a); final Comparable 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