data_table_demo.dart 10.3 KB
Newer Older
1 2 3 4 5
// Copyright 2016 The Chromium Authors. 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';
6
import 'package:flutter/rendering.dart';
7

Adam Barth's avatar
Adam Barth committed
8 9
class Dessert {
  Dessert(this.name, this.calories, this.fat, this.carbs, this.protein, this.sodium, this.calcium, this.iron);
10 11 12 13 14 15 16 17 18 19 20 21
  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;
}

Adam Barth's avatar
Adam Barth committed
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
class DessertDataSource extends DataTableSource {
  final List<Dessert> _desserts = <Dessert>[
    new Dessert('Frozen yogurt',                        159,  6.0,  24,  4.0,  87, 14,  1),
    new Dessert('Ice cream sandwich',                   237,  9.0,  37,  4.3, 129,  8,  1),
    new Dessert('Eclair',                               262, 16.0,  24,  6.0, 337,  6,  7),
    new Dessert('Cupcake',                              305,  3.7,  67,  4.3, 413,  3,  8),
    new Dessert('Gingerbread',                          356, 16.0,  49,  3.9, 327,  7, 16),
    new Dessert('Jelly bean',                           375,  0.0,  94,  0.0,  50,  0,  0),
    new Dessert('Lollipop',                             392,  0.2,  98,  0.0,  38,  0,  2),
    new Dessert('Honeycomb',                            408,  3.2,  87,  6.5, 562,  0, 45),
    new Dessert('Donut',                                452, 25.0,  51,  4.9, 326,  2, 22),
    new Dessert('KitKat',                               518, 26.0,  65,  7.0,  54, 12,  6),

    new Dessert('Frozen yogurt with sugar',             168,  6.0,  26,  4.0,  87, 14,  1),
    new Dessert('Ice cream sandwich with sugar',        246,  9.0,  39,  4.3, 129,  8,  1),
    new Dessert('Eclair with sugar',                    271, 16.0,  26,  6.0, 337,  6,  7),
    new Dessert('Cupcake with sugar',                   314,  3.7,  69,  4.3, 413,  3,  8),
    new Dessert('Gingerbread with sugar',               345, 16.0,  51,  3.9, 327,  7, 16),
    new Dessert('Jelly bean with sugar',                364,  0.0,  96,  0.0,  50,  0,  0),
    new Dessert('Lollipop with sugar',                  401,  0.2, 100,  0.0,  38,  0,  2),
    new Dessert('Honeycomb with sugar',                 417,  3.2,  89,  6.5, 562,  0, 45),
    new Dessert('Donut with sugar',                     461, 25.0,  53,  4.9, 326,  2, 22),
    new Dessert('KitKat with sugar',                    527, 26.0,  67,  7.0,  54, 12,  6),

    new Dessert('Frozen yogurt with honey',             223,  6.0,  36,  4.0,  87, 14,  1),
    new Dessert('Ice cream sandwich with honey',        301,  9.0,  49,  4.3, 129,  8,  1),
    new Dessert('Eclair with honey',                    326, 16.0,  36,  6.0, 337,  6,  7),
    new Dessert('Cupcake with honey',                   369,  3.7,  79,  4.3, 413,  3,  8),
    new Dessert('Gingerbread with honey',               420, 16.0,  61,  3.9, 327,  7, 16),
    new Dessert('Jelly bean with honey',                439,  0.0, 106,  0.0,  50,  0,  0),
    new Dessert('Lollipop with honey',                  456,  0.2, 110,  0.0,  38,  0,  2),
    new Dessert('Honeycomb with honey',                 472,  3.2,  99,  6.5, 562,  0, 45),
    new Dessert('Donut with honey',                     516, 25.0,  63,  4.9, 326,  2, 22),
    new Dessert('KitKat with honey',                    582, 26.0,  77,  7.0,  54, 12,  6),

    new Dessert('Frozen yogurt with milk',              262,  8.4,  36, 12.0, 194, 44,  1),
    new Dessert('Ice cream sandwich with milk',         339, 11.4,  49, 12.3, 236, 38,  1),
    new Dessert('Eclair with milk',                     365, 18.4,  36, 14.0, 444, 36,  7),
    new Dessert('Cupcake with milk',                    408,  6.1,  79, 12.3, 520, 33,  8),
    new Dessert('Gingerbread with milk',                459, 18.4,  61, 11.9, 434, 37, 16),
    new Dessert('Jelly bean with milk',                 478,  2.4, 106,  8.0, 157, 30,  0),
    new Dessert('Lollipop with milk',                   495,  2.6, 110,  8.0, 145, 30,  2),
    new Dessert('Honeycomb with milk',                  511,  5.6,  99, 14.5, 669, 30, 45),
    new Dessert('Donut with milk',                      555, 27.4,  63, 12.9, 433, 32, 22),
    new Dessert('KitKat with milk',                     621, 28.4,  77, 15.0, 161, 42,  6),

    new Dessert('Coconut slice and frozen yogurt',      318, 21.0,  31,  5.5,  96, 14,  7),
    new Dessert('Coconut slice and ice cream sandwich', 396, 24.0,  44,  5.8, 138,  8,  7),
    new Dessert('Coconut slice and eclair',             421, 31.0,  31,  7.5, 346,  6, 13),
    new Dessert('Coconut slice and cupcake',            464, 18.7,  74,  5.8, 422,  3, 14),
    new Dessert('Coconut slice and gingerbread',        515, 31.0,  56,  5.4, 316,  7, 22),
    new Dessert('Coconut slice and jelly bean',         534, 15.0, 101,  1.5,  59,  0,  6),
    new Dessert('Coconut slice and lollipop',           551, 15.2, 105,  1.5,  47,  0,  8),
    new Dessert('Coconut slice and honeycomb',          567, 18.2,  94,  8.0, 571,  0, 51),
    new Dessert('Coconut slice and donut',              611, 40.0,  58,  6.4, 335,  2, 28),
    new Dessert('Coconut slice and KitKat',             677, 41.0,  72,  8.5,  63, 12, 12),
78 79
  ];

Adam Barth's avatar
Adam Barth committed
80 81
  void _sort<T>(Comparable<T> getField(Dessert d), bool ascending) {
    _desserts.sort((Dessert a, Dessert b) {
82
      if (!ascending) {
Adam Barth's avatar
Adam Barth committed
83
        final Dessert c = a;
84 85 86
        a = b;
        b = c;
      }
87 88
      final Comparable<T> aValue = getField(a);
      final Comparable<T> bValue = getField(b);
89 90 91 92 93
      return Comparable.compare(aValue, bValue);
    });
    notifyListeners();
  }

94 95
  int _selectedCount = 0;

96 97 98
  @override
  DataRow getRow(int index) {
    assert(index >= 0);
Adam Barth's avatar
Adam Barth committed
99
    if (index >= _desserts.length)
100
      return null;
Adam Barth's avatar
Adam Barth committed
101
    final Dessert dessert = _desserts[index];
102 103
    return new DataRow.byIndex(
      index: index,
Adam Barth's avatar
Adam Barth committed
104
      selected: dessert.selected,
105
      onSelectChanged: (bool value) {
Adam Barth's avatar
Adam Barth committed
106
        if (dessert.selected != value) {
107 108
          _selectedCount += value ? 1 : -1;
          assert(_selectedCount >= 0);
Adam Barth's avatar
Adam Barth committed
109
          dessert.selected = value;
110 111
          notifyListeners();
        }
112 113
      },
      cells: <DataCell>[
Adam Barth's avatar
Adam Barth committed
114 115 116 117 118 119 120 121
        new DataCell(new Text('${dessert.name}')),
        new DataCell(new Text('${dessert.calories}')),
        new DataCell(new Text('${dessert.fat.toStringAsFixed(1)}')),
        new DataCell(new Text('${dessert.carbs}')),
        new DataCell(new Text('${dessert.protein.toStringAsFixed(1)}')),
        new DataCell(new Text('${dessert.sodium}')),
        new DataCell(new Text('${dessert.calcium}%')),
        new DataCell(new Text('${dessert.iron}%')),
122 123 124 125 126
      ]
    );
  }

  @override
Adam Barth's avatar
Adam Barth committed
127
  int get rowCount => _desserts.length;
128 129

  @override
130
  bool get isRowCountApproximate => false;
131 132 133 134 135

  @override
  int get selectedRowCount => _selectedCount;

  void _selectAll(bool checked) {
Adam Barth's avatar
Adam Barth committed
136 137 138
    for (Dessert dessert in _desserts)
      dessert.selected = checked;
    _selectedCount = checked ? _desserts.length : 0;
139 140
    notifyListeners();
  }
141 142
}

143
class DataTableDemo extends StatefulWidget {
144
  static const String routeName = '/material/data-table';
145

146 147 148 149 150
  @override
  _DataTableDemoState createState() => new _DataTableDemoState();
}

class _DataTableDemoState extends State<DataTableDemo> {
151
  int _rowsPerPage = PaginatedDataTable.defaultRowsPerPage;
152 153
  int _sortColumnIndex;
  bool _sortAscending = true;
154
  final DessertDataSource _dessertsDataSource = new DessertDataSource();
155

Adam Barth's avatar
Adam Barth committed
156 157
  void _sort<T>(Comparable<T> getField(Dessert d), int columnIndex, bool ascending) {
    _dessertsDataSource._sort<T>(getField, ascending);
158 159 160 161 162 163 164 165 166
    setState(() {
      _sortColumnIndex = columnIndex;
      _sortAscending = ascending;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
167
      appBar: new AppBar(title: const Text('Data tables')),
168
      body: new ListView(
169
        padding: const EdgeInsets.all(20.0),
170
        children: <Widget>[
171
          new PaginatedDataTable(
172
            header: const Text('Nutrition'),
173 174 175 176
            rowsPerPage: _rowsPerPage,
            onRowsPerPageChanged: (int value) { setState(() { _rowsPerPage = value; }); },
            sortColumnIndex: _sortColumnIndex,
            sortAscending: _sortAscending,
Adam Barth's avatar
Adam Barth committed
177
            onSelectAll: _dessertsDataSource._selectAll,
178 179
            columns: <DataColumn>[
              new DataColumn(
180
                label: const Text('Dessert (100g serving)'),
Adam Barth's avatar
Adam Barth committed
181
                onSort: (int columnIndex, bool ascending) => _sort<String>((Dessert d) => d.name, columnIndex, ascending)
182 183
              ),
              new DataColumn(
184
                label: const Text('Calories'),
185 186
                tooltip: 'The total amount of food energy in the given serving size.',
                numeric: true,
Adam Barth's avatar
Adam Barth committed
187
                onSort: (int columnIndex, bool ascending) => _sort<num>((Dessert d) => d.calories, columnIndex, ascending)
188 189
              ),
              new DataColumn(
190
                label: const Text('Fat (g)'),
191
                numeric: true,
Adam Barth's avatar
Adam Barth committed
192
                onSort: (int columnIndex, bool ascending) => _sort<num>((Dessert d) => d.fat, columnIndex, ascending)
193 194
              ),
              new DataColumn(
195
                label: const Text('Carbs (g)'),
196
                numeric: true,
Adam Barth's avatar
Adam Barth committed
197
                onSort: (int columnIndex, bool ascending) => _sort<num>((Dessert d) => d.carbs, columnIndex, ascending)
198 199
              ),
              new DataColumn(
200
                label: const Text('Protein (g)'),
201
                numeric: true,
Adam Barth's avatar
Adam Barth committed
202
                onSort: (int columnIndex, bool ascending) => _sort<num>((Dessert d) => d.protein, columnIndex, ascending)
203 204
              ),
              new DataColumn(
205
                label: const Text('Sodium (mg)'),
206
                numeric: true,
Adam Barth's avatar
Adam Barth committed
207
                onSort: (int columnIndex, bool ascending) => _sort<num>((Dessert d) => d.sodium, columnIndex, ascending)
208 209
              ),
              new DataColumn(
210
                label: const Text('Calcium (%)'),
211 212
                tooltip: 'The amount of calcium as a percentage of the recommended daily amount.',
                numeric: true,
Adam Barth's avatar
Adam Barth committed
213
                onSort: (int columnIndex, bool ascending) => _sort<num>((Dessert d) => d.calcium, columnIndex, ascending)
214 215
              ),
              new DataColumn(
216
                label: const Text('Iron (%)'),
217
                numeric: true,
Adam Barth's avatar
Adam Barth committed
218
                onSort: (int columnIndex, bool ascending) => _sort<num>((Dessert d) => d.iron, columnIndex, ascending)
219 220
              ),
            ],
Adam Barth's avatar
Adam Barth committed
221
            source: _dessertsDataSource
222 223 224 225 226 227
          )
        ]
      )
    );
  }
}