list_demo.dart 7.55 KB
Newer Older
Hans Muller's avatar
Hans Muller committed
1 2 3 4 5 6
// 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';

7 8 9 10 11 12 13 14 15 16 17 18 19 20
enum _MaterialListType {
  /// A list tile that contains a single line of text.
  oneLine,

  /// A list tile that contains a [CircleAvatar] followed by a single line of text.
  oneLineWithAvatar,

  /// A list tile that contains two lines of text.
  twoLine,

  /// A list tile that contains three lines of text.
  threeLine,
}

21
class ListDemo extends StatefulWidget {
22
  const ListDemo({ Key key }) : super(key: key);
Hans Muller's avatar
Hans Muller committed
23

24
  static const String routeName = '/material/list';
25

26
  @override
27
  _ListDemoState createState() => new _ListDemoState();
Hans Muller's avatar
Hans Muller committed
28 29
}

30
class _ListDemoState extends State<ListDemo> {
31
  static final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
Hans Muller's avatar
Hans Muller committed
32

33
  PersistentBottomSheetController<Null> _bottomSheet;
34
  _MaterialListType _itemType = _MaterialListType.threeLine;
Hans Muller's avatar
Hans Muller committed
35 36 37 38
  bool _dense = false;
  bool _showAvatars = true;
  bool _showIcons = false;
  bool _showDividers = false;
Hans Muller's avatar
Hans Muller committed
39 40
  bool _reverseSort = false;
  List<String> items = <String>[
41
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
Hans Muller's avatar
Hans Muller committed
42 43
  ];

44
  void changeItemType(_MaterialListType type) {
Hans Muller's avatar
Hans Muller committed
45
    setState(() {
46
      _itemType = type;
Hans Muller's avatar
Hans Muller committed
47 48 49 50
    });
    _bottomSheet?.setState(() { });
  }

51 52
  void _showConfigurationSheet() {
    final PersistentBottomSheetController<Null> bottomSheet = scaffoldKey.currentState.showBottomSheet((BuildContext bottomSheetContext) {
Hans Muller's avatar
Hans Muller committed
53
      return new Container(
54 55
        decoration: const BoxDecoration(
          border: const Border(top: const BorderSide(color: Colors.black26)),
Hans Muller's avatar
Hans Muller committed
56
        ),
57
        child: new ListView(
58
          shrinkWrap: true,
59
          primary: false,
Hans Muller's avatar
Hans Muller committed
60
          children: <Widget>[
61 62 63 64 65 66 67 68 69 70
            new MergeSemantics(
              child: new ListTile(
                dense: true,
                title: const Text('One-line'),
                trailing: new Radio<_MaterialListType>(
                  value: _showAvatars ? _MaterialListType.oneLineWithAvatar : _MaterialListType.oneLine,
                  groupValue: _itemType,
                  onChanged: changeItemType,
                )
              ),
Hans Muller's avatar
Hans Muller committed
71
            ),
72 73 74 75 76 77 78 79 80 81
            new MergeSemantics(
              child: new ListTile(
                dense: true,
                title: const Text('Two-line'),
                trailing: new Radio<_MaterialListType>(
                  value: _MaterialListType.twoLine,
                  groupValue: _itemType,
                  onChanged: changeItemType,
                )
              ),
Hans Muller's avatar
Hans Muller committed
82
            ),
83 84 85 86 87 88 89 90 91
            new MergeSemantics(
              child: new ListTile(
                dense: true,
                title: const Text('Three-line'),
                trailing: new Radio<_MaterialListType>(
                  value: _MaterialListType.threeLine,
                  groupValue: _itemType,
                  onChanged: changeItemType,
                ),
92
              ),
Hans Muller's avatar
Hans Muller committed
93
            ),
94 95 96 97 98 99 100 101 102 103 104 105 106
            new MergeSemantics(
              child: new ListTile(
                dense: true,
                title: const Text('Show avatar'),
                trailing: new Checkbox(
                  value: _showAvatars,
                  onChanged: (bool value) {
                    setState(() {
                      _showAvatars = value;
                    });
                    _bottomSheet?.setState(() { });
                  },
                ),
107
              ),
Hans Muller's avatar
Hans Muller committed
108
            ),
109 110 111 112 113 114 115 116 117 118 119 120 121
            new MergeSemantics(
              child: new ListTile(
                dense: true,
                title: const Text('Show icon'),
                trailing: new Checkbox(
                  value: _showIcons,
                  onChanged: (bool value) {
                    setState(() {
                      _showIcons = value;
                    });
                    _bottomSheet?.setState(() { });
                  },
                ),
122
              ),
Hans Muller's avatar
Hans Muller committed
123
            ),
124 125 126 127 128 129 130 131 132 133 134 135 136
            new MergeSemantics(
              child: new ListTile(
                dense: true,
                title: const Text('Show dividers'),
                trailing: new Checkbox(
                  value: _showDividers,
                  onChanged: (bool value) {
                    setState(() {
                      _showDividers = value;
                    });
                    _bottomSheet?.setState(() { });
                  },
                ),
137
              ),
Hans Muller's avatar
Hans Muller committed
138
            ),
139 140 141 142 143 144 145 146 147 148 149 150 151
            new MergeSemantics(
              child: new ListTile(
                dense: true,
                title: const Text('Dense layout'),
                trailing: new Checkbox(
                  value: _dense,
                  onChanged: (bool value) {
                    setState(() {
                      _dense = value;
                    });
                    _bottomSheet?.setState(() { });
                  },
                ),
152 153 154 155
              ),
            ),
          ],
        ),
Hans Muller's avatar
Hans Muller committed
156 157
      );
    });
158 159 160 161 162 163 164 165 166 167 168 169

    setState(() {
      _bottomSheet = bottomSheet;
    });

    _bottomSheet.closed.whenComplete(() {
      if (mounted) {
        setState(() {
          _bottomSheet = null;
        });
      }
    });
Hans Muller's avatar
Hans Muller committed
170 171
  }

172
  Widget buildListTile(BuildContext context, String item) {
Hans Muller's avatar
Hans Muller committed
173
    Widget secondary;
174
    if (_itemType == _MaterialListType.twoLine) {
175
      secondary = const Text('Additional item information.');
176
    } else if (_itemType == _MaterialListType.threeLine) {
177
      secondary = const Text(
178
        'Even more additional list item information appears on line three.',
Hans Muller's avatar
Hans Muller committed
179 180
      );
    }
181 182 183 184 185 186 187 188 189
    return new MergeSemantics(
      child: new ListTile(
        isThreeLine: _itemType == _MaterialListType.threeLine,
        dense: _dense,
        leading: _showAvatars ? new ExcludeSemantics(child: new CircleAvatar(child: new Text(item))) : null,
        title: new Text('This item represents $item.'),
        subtitle: secondary,
        trailing: _showIcons ? new Icon(Icons.info, color: Theme.of(context).disabledColor) : null,
      ),
Hans Muller's avatar
Hans Muller committed
190 191 192
    );
  }

193
  @override
Hans Muller's avatar
Hans Muller committed
194
  Widget build(BuildContext context) {
195
    final String layoutText = _dense ? ' \u2013 Dense' : '';
196 197
    String itemTypeText;
    switch (_itemType) {
198 199
      case _MaterialListType.oneLine:
      case _MaterialListType.oneLineWithAvatar:
200
        itemTypeText = 'Single-line';
Hans Muller's avatar
Hans Muller committed
201
        break;
202
      case _MaterialListType.twoLine:
203
        itemTypeText = 'Two-line';
Hans Muller's avatar
Hans Muller committed
204
        break;
205
      case _MaterialListType.threeLine:
206
        itemTypeText = 'Three-line';
Hans Muller's avatar
Hans Muller committed
207 208
        break;
    }
Hans Muller's avatar
Hans Muller committed
209

210
    Iterable<Widget> listTiles = items.map((String item) => buildListTile(context, item));
Hans Muller's avatar
Hans Muller committed
211
    if (_showDividers)
212
      listTiles = ListTile.divideTiles(context: context, tiles: listTiles);
Hans Muller's avatar
Hans Muller committed
213

Hans Muller's avatar
Hans Muller committed
214 215
    return new Scaffold(
      key: scaffoldKey,
216
      appBar: new AppBar(
217
        title: new Text('Scrolling list\n$itemTypeText$layoutText'),
218
        actions: <Widget>[
Hans Muller's avatar
Hans Muller committed
219
          new IconButton(
220
            icon: const Icon(Icons.sort_by_alpha),
Hans Muller's avatar
Hans Muller committed
221 222 223 224 225 226
            tooltip: 'Sort',
            onPressed: () {
              setState(() {
                _reverseSort = !_reverseSort;
                items.sort((String a, String b) => _reverseSort ? b.compareTo(a) : a.compareTo(b));
              });
227
            },
Hans Muller's avatar
Hans Muller committed
228 229
          ),
          new IconButton(
230
            icon: const Icon(Icons.more_vert),
Hans Muller's avatar
Hans Muller committed
231
            tooltip: 'Show menu',
232
            onPressed: _bottomSheet == null ? _showConfigurationSheet : null,
233 234
          ),
        ],
Hans Muller's avatar
Hans Muller committed
235
      ),
236
      body: new Scrollbar(
237
        child: new ListView(
238
          padding: new EdgeInsets.symmetric(vertical: _dense ? 4.0 : 8.0),
239
          children: listTiles.toList(),
240 241
        ),
      ),
Hans Muller's avatar
Hans Muller committed
242 243 244
    );
  }
}