buttons_demo.dart 12.3 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4 5 6
// 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
import '../../gallery/demo.dart';
8

9 10
const String _elevatedText =
    'Elevated buttons add dimension to mostly flat layouts. They emphasize '
11
    'functions on busy or wide spaces.';
12

13
const String _elevatedCode = 'buttons_elevated';
14

15 16
const String _textText = 'A text button displays an ink splash on press '
    'but does not lift. Use text buttons on toolbars, in dialogs and '
17
    'inline with padding';
18

19
const String _textCode = 'buttons_text';
20

21 22 23
const String _outlinedText =
    'Outlined buttons become opaque and elevate when pressed. They are often '
    'paired with elevated buttons to indicate an alternative, secondary action.';
24

25
const String _outlinedCode = 'buttons_outlined';
26

27
const String _dropdownText =
28
    "A dropdown button displays a menu that's used to select a value from a "
29 30
    'small set of values. The button displays the current value and a down '
    'arrow.';
31

32
const String _dropdownCode = 'buttons_dropdown';
33

34
const String _iconText =
35
    'IconButtons are appropriate for toggle buttons that allow a single choice '
36
    "to be selected or deselected, such as adding or removing an item's star.";
37

38
const String _iconCode = 'buttons_icon';
39 40

const String _actionText =
41 42 43 44
    'Floating action buttons are used for a promoted action. They are '
    'distinguished by a circled icon floating above the UI and can have motion '
    'behaviors that include morphing, launching, and a transferring anchor '
    'point.';
45

46
const String _actionCode = 'buttons_action';
47

48
class ButtonsDemo extends StatefulWidget {
49
  static const String routeName = '/material/buttons';
50

51
  @override
52
  _ButtonsDemoState createState() => _ButtonsDemoState();
53 54 55
}

class _ButtonsDemoState extends State<ButtonsDemo> {
56
  OutlinedBorder _buttonShape;
57

58
  @override
59
  Widget build(BuildContext context) {
60
    final List<ComponentDemoTabData> demos = <ComponentDemoTabData>[
61
      ComponentDemoTabData(
62 63 64 65 66
        tabName: 'ELEVATED',
        description: _elevatedText,
        demoWidget: buildElevatedButton(_buttonShape),
        exampleCodeTag: _elevatedCode,
        documentationUrl: 'https://docs.flutter.io/flutter/material/ElevatedButton-class.html',
67
      ),
68
      ComponentDemoTabData(
69 70 71 72 73
        tabName: 'TEXT',
        description: _textText,
        demoWidget: buildTextButton(_buttonShape),
        exampleCodeTag: _textCode,
        documentationUrl: 'https://docs.flutter.io/flutter/material/TextButton-class.html',
74
      ),
75
      ComponentDemoTabData(
76 77 78 79 80
        tabName: 'OUTLINED',
        description: _outlinedText,
        demoWidget: buildOutlinedButton(_buttonShape),
        exampleCodeTag: _outlinedCode,
        documentationUrl: 'https://docs.flutter.io/flutter/material/OutlinedButton-class.html',
81
      ),
82
      ComponentDemoTabData(
83 84
        tabName: 'DROPDOWN',
        description: _dropdownText,
85
        demoWidget: buildDropdownButton(),
86
        exampleCodeTag: _dropdownCode,
87
        documentationUrl: 'https://docs.flutter.io/flutter/material/DropdownButton-class.html',
88
      ),
89
      ComponentDemoTabData(
90 91
        tabName: 'ICON',
        description: _iconText,
92
        demoWidget: buildIconButton(),
93
        exampleCodeTag: _iconCode,
94
        documentationUrl: 'https://docs.flutter.io/flutter/material/IconButton-class.html',
95
      ),
96
      ComponentDemoTabData(
97 98
        tabName: 'ACTION',
        description: _actionText,
99
        demoWidget: buildActionButton(),
100
        exampleCodeTag: _actionCode,
101
        documentationUrl: 'https://docs.flutter.io/flutter/material/FloatingActionButton-class.html',
102
      ),
103 104
    ];

105
    return TabbedComponentDemoScaffold(
106
      title: 'Buttons',
107
      demos: demos,
108
      actions: <Widget>[
109
        IconButton(
110
          icon: const Icon(Icons.sentiment_very_satisfied, semanticLabel: 'Update shape'),
111 112 113 114 115 116 117
          onPressed: () {
            setState(() {
              _buttonShape = _buttonShape == null ? const StadiumBorder() : null;
            });
          },
        ),
      ],
118 119 120
    );
  }

121 122
  Widget buildElevatedButton(OutlinedBorder shape) {
    final ButtonStyle style = ElevatedButton.styleFrom(shape: shape);
123
    return Align(
124
      alignment: const Alignment(0.0, -0.2),
125
      child: Column(
126
        mainAxisSize: MainAxisSize.min,
127
        children: <Widget>[
128
          ButtonBar(
129 130
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
131 132 133
              ElevatedButton(
                style: style,
                child: const Text('ELEVATED BUTTON', semanticsLabel: 'ELEVATED BUTTON 1'),
134 135 136 137
                onPressed: () {
                  // Perform some action
                },
              ),
138
              const ElevatedButton(
139
                child: Text('DISABLED', semanticsLabel: 'DISABLED BUTTON 1'),
140 141 142 143
                onPressed: null,
              ),
            ],
          ),
144
          ButtonBar(
145 146
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
147 148
              ElevatedButton.icon(
                style: style,
149
                icon: const Icon(Icons.add, size: 18.0),
150
                label: const Text('ELEVATED BUTTON', semanticsLabel: 'ELEVATED BUTTON 2'),
151 152 153 154
                onPressed: () {
                  // Perform some action
                },
              ),
155 156
              ElevatedButton.icon(
                style: style,
157
                icon: const Icon(Icons.add, size: 18.0),
158
                label: const Text('DISABLED', semanticsLabel: 'DISABLED BUTTON 2'),
159 160 161
                onPressed: null,
              ),
            ],
162
          ),
163 164
        ],
      ),
165 166 167
    );
  }

168 169
  Widget buildTextButton(OutlinedBorder shape) {
    final ButtonStyle style = ElevatedButton.styleFrom(shape: shape);
170
    return Align(
171
      alignment: const Alignment(0.0, -0.2),
172
      child: Column(
173 174
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
175
          ButtonBar(
176 177
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
178 179 180
              TextButton(
                style: style,
                child: const Text('TEXT BUTTON', semanticsLabel: 'TEXT BUTTON 1'),
181 182 183 184
                onPressed: () {
                  // Perform some action
                },
              ),
185
              const TextButton(
186
                child: Text('DISABLED', semanticsLabel: 'DISABLED BUTTON 3',),
187 188 189 190
                onPressed: null,
              ),
            ],
          ),
191
          ButtonBar(
192 193
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
194 195
              TextButton.icon(
                style: style,
196
                icon: const Icon(Icons.add_circle_outline, size: 18.0),
197
                label: const Text('TEXT BUTTON', semanticsLabel: 'TEXT BUTTON 2'),
198 199 200 201
                onPressed: () {
                  // Perform some action
                },
              ),
202 203
              TextButton.icon(
                style: style,
204
                icon: const Icon(Icons.add_circle_outline, size: 18.0),
205
                label: const Text('DISABLED', semanticsLabel: 'DISABLED BUTTON 4'),
206 207 208 209 210 211 212 213 214
                onPressed: null,
              ),
            ],
          ),
        ],
      ),
    );
  }

215 216
  Widget buildOutlinedButton(OutlinedBorder shape) {
    final ButtonStyle style = ElevatedButton.styleFrom(shape: shape);
217
    return Align(
218
      alignment: const Alignment(0.0, -0.2),
219
      child: Column(
220
        mainAxisSize: MainAxisSize.min,
221
        children: <Widget>[
222
          ButtonBar(
223 224
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
225 226 227
              OutlinedButton(
                style: style,
                child: const Text('OUTLINED BUTTON', semanticsLabel: 'OUTLINED BUTTON 1'),
228 229 230 231
                onPressed: () {
                  // Perform some action
                },
              ),
232 233 234
              OutlinedButton(
                style: style,
                child: const Text('DISABLED', semanticsLabel: 'DISABLED BUTTON 5'),
235 236 237 238
                onPressed: null,
              ),
            ],
          ),
239
          ButtonBar(
240 241
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
242 243
              OutlinedButton.icon(
                style: style,
244
                icon: const Icon(Icons.add, size: 18.0),
245
                label: const Text('OUTLINED BUTTON', semanticsLabel: 'OUTLINED BUTTON 2'),
246 247 248 249
                onPressed: () {
                  // Perform some action
                },
              ),
250
              OutlinedButton.icon(
251
                icon: const Icon(Icons.add, size: 18.0),
252
                label: const Text('DISABLED', semanticsLabel: 'DISABLED BUTTON 6'),
253 254 255
                onPressed: null,
              ),
            ],
256
          ),
257 258
        ],
      ),
259 260 261
    );
  }

262 263
  // https://en.wikipedia.org/wiki/Free_Four
  String dropdown1Value = 'Free';
264 265
  String dropdown2Value;
  String dropdown3Value = 'Four';
266 267

  Widget buildDropdownButton() {
268
    return Padding(
269
      padding: const EdgeInsets.all(24.0),
270
      child: Column(
271 272
        mainAxisAlignment: MainAxisAlignment.start,
        children: <Widget>[
273
          ListTile(
274
            title: const Text('Simple dropdown:'),
275
            trailing: DropdownButton<String>(
276 277 278
              value: dropdown1Value,
              onChanged: (String newValue) {
                setState(() {
279
                  dropdown1Value = newValue;
280 281
                });
              },
282
              items: <String>['One', 'Two', 'Free', 'Four'].map<DropdownMenuItem<String>>((String value) {
283
                return DropdownMenuItem<String>(
284
                  value: value,
285
                  child: Text(value),
286 287 288
                );
              }).toList(),
            ),
289
          ),
290
          const SizedBox(
291
            height: 24.0,
292
          ),
293
          ListTile(
294
            title: const Text('Dropdown with a hint:'),
295
            trailing: DropdownButton<String>(
296
              value: dropdown2Value,
297
              hint: const Text('Choose'),
298 299
              onChanged: (String newValue) {
                setState(() {
300
                  dropdown2Value = newValue;
301 302
                });
              },
303
              items: <String>['One', 'Two', 'Free', 'Four'].map<DropdownMenuItem<String>>((String value) {
304
                return DropdownMenuItem<String>(
305
                  value: value,
306
                  child: Text(value),
307 308 309
                );
              }).toList(),
            ),
310
          ),
311
          const SizedBox(
312 313
            height: 24.0,
          ),
314
          ListTile(
315
            title: const Text('Scrollable dropdown:'),
316
            trailing: DropdownButton<String>(
317 318 319 320 321 322 323 324
              value: dropdown3Value,
              onChanged: (String newValue) {
                setState(() {
                  dropdown3Value = newValue;
                });
              },
              items: <String>[
                  'One', 'Two', 'Free', 'Four', 'Can', 'I', 'Have', 'A', 'Little',
325
                  'Bit', 'More', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten',
326
                 ]
327
                .map<DropdownMenuItem<String>>((String value) {
328
                  return DropdownMenuItem<String>(
329
                    value: value,
330
                    child: Text(value),
331 332 333 334 335
                  );
                })
                .toList(),
             ),
          ),
336 337
        ],
      ),
338 339 340
    );
  }

341 342 343
  bool iconButtonToggle = false;

  Widget buildIconButton() {
344
    return Align(
345
      alignment: const Alignment(0.0, -0.2),
346
      child: Row(
347
        mainAxisSize: MainAxisSize.min,
348
        children: <Widget>[
349
          IconButton(
350 351 352 353
            icon: const Icon(
              Icons.thumb_up,
              semanticLabel: 'Thumbs up',
            ),
354 355 356
            onPressed: () {
              setState(() => iconButtonToggle = !iconButtonToggle);
            },
357
            color: iconButtonToggle ? Theme.of(context).primaryColor : null,
358
          ),
359
          const IconButton(
360
            icon: Icon(
361
              Icons.thumb_up,
362
              semanticLabel: 'Thumbs not up',
363
            ),
364
            onPressed: null,
365
          ),
366
        ]
367
        .map<Widget>((Widget button) => SizedBox(width: 64.0, height: 64.0, child: button))
368 369
        .toList(),
      ),
370 371 372
    );
  }

373
  Widget buildActionButton() {
374
    return Align(
375
      alignment: const Alignment(0.0, -0.2),
376
      child: FloatingActionButton(
377
        child: const Icon(Icons.add),
378 379
        onPressed: () {
          // Perform some action
380
        },
381
        tooltip: 'floating action button',
382
      ),
383 384 385
    );
  }
}