flat_button.dart 9.26 KB
Newer Older
1 2 3 4
// Copyright 2015 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.

5
import 'package:flutter/foundation.dart';
6
import 'package:flutter/widgets.dart';
7

8
import 'button.dart';
9
import 'button_theme.dart';
10
import 'material_button.dart';
11
import 'theme.dart';
12
import 'theme_data.dart';
13

14 15
/// A material design "flat button".
///
16 17
/// A flat button is a text label displayed on a (zero elevation) [Material]
/// widget that reacts to touches by filling with color.
18 19 20 21 22 23 24 25 26
///
/// Use flat buttons on toolbars, in dialogs, or inline with other content but
/// offset from that content with padding so that the button's presence is
/// obvious. Flat buttons intentionally do not have visible borders and must
/// therefore rely on their position relative to other content for context. In
/// dialogs and cards, they should be grouped together in one of the bottom
/// corners. Avoid using flat buttons where they would blend in with other
/// content, for example in the middle of lists.
///
27 28 29 30 31
/// Material design flat buttons have an all-caps label, some internal padding,
/// and some defined dimensions. To have a part of your application be
/// interactive, with ink splashes, without also committing to these stylistic
/// choices, consider using [InkWell] instead.
///
32
/// If the [onPressed] and [onLongPress] callbacks are null, then this button will be disabled,
33
/// will not react to touch, and will be colored as specified by
34 35 36 37
/// the [disabledColor] property instead of the [color] property. If you are
/// trying to change the button's [color] and it is not having any effect, check
/// that you are passing a non-null [onPressed] handler.
///
38
/// Flat buttons have a minimum size of 88.0 by 36.0 which can be overridden
39
/// with [ButtonTheme].
40
///
41 42
/// The [clipBehavior] argument must not be null.
///
43 44 45 46
/// {@tool sample}
///
/// This example shows a simple [FlatButton].
///
47 48
/// ![A simple FlatButton](https://flutter.github.io/assets-for-api-docs/assets/material/flat_button.png)
///
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
/// ```dart
/// FlatButton(
///   onPressed: () {
///     /*...*/
///   },
///   child: Text(
///     "Flat Button",
///   ),
/// )
/// ```
/// {@end-tool}
///
/// {@tool sample}
///
/// This example shows a [FlatButton] that is normally white-on-blue,
/// with splashes rendered in a different shade of blue.
/// It turns black-on-grey when disabled.
/// The button has 8px of padding on each side, and the text is 20px high.
///
68 69
/// ![A FlatButton with white text on a blue background](https://flutter.github.io/assets-for-api-docs/assets/material/flat_button_properties.png)
///
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
/// ```dart
/// FlatButton(
///   color: Colors.blue,
///   textColor: Colors.white,
///   disabledColor: Colors.grey,
///   disabledTextColor: Colors.black,
///   padding: EdgeInsets.all(8.0),
///   splashColor: Colors.blueAccent,
///   onPressed: () {
///     /*...*/
///   },
///   child: Text(
///     "Flat Button",
///     style: TextStyle(fontSize: 20.0),
///   ),
/// )
/// ```
/// {@end-tool}
///
89
/// See also:
90
///
91
///  * [RaisedButton], a filled button whose material elevates when pressed.
92 93
///  * [DropdownButton], which offers the user a choice of a number of options.
///  * [SimpleDialogOption], which is used in [SimpleDialog]s.
94
///  * [IconButton], to create buttons that just contain icons.
95
///  * [InkWell], which implements the ink splash part of a flat button.
96
///  * [RawMaterialButton], the widget this widget is based on.
97
///  * <https://material.io/design/components/buttons.html>
98
class FlatButton extends MaterialButton {
99
  /// Create a simple text button.
100 101
  ///
  /// The [autofocus] and [clipBehavior] arguments must not be null.
102
  const FlatButton({
103
    Key key,
104
    @required VoidCallback onPressed,
105
    VoidCallback onLongPress,
106 107 108 109 110 111
    ValueChanged<bool> onHighlightChanged,
    ButtonTextTheme textTheme,
    Color textColor,
    Color disabledTextColor,
    Color color,
    Color disabledColor,
112 113
    Color focusColor,
    Color hoverColor,
114 115 116 117 118
    Color highlightColor,
    Color splashColor,
    Brightness colorBrightness,
    EdgeInsetsGeometry padding,
    ShapeBorder shape,
119
    Clip clipBehavior = Clip.none,
120
    FocusNode focusNode,
121
    bool autofocus = false,
122 123
    MaterialTapTargetSize materialTapTargetSize,
    @required Widget child,
124 125
  }) : assert(clipBehavior != null),
       assert(autofocus != null),
126
       super(
127 128
         key: key,
         onPressed: onPressed,
129
         onLongPress: onLongPress,
130 131 132 133 134 135
         onHighlightChanged: onHighlightChanged,
         textTheme: textTheme,
         textColor: textColor,
         disabledTextColor: disabledTextColor,
         color: color,
         disabledColor: disabledColor,
136 137
         focusColor: focusColor,
         hoverColor: hoverColor,
138 139 140 141 142 143
         highlightColor: highlightColor,
         splashColor: splashColor,
         colorBrightness: colorBrightness,
         padding: padding,
         shape: shape,
         clipBehavior: clipBehavior,
144
         focusNode: focusNode,
145
         autofocus: autofocus,
146 147 148
         materialTapTargetSize: materialTapTargetSize,
         child: child,
      );
149 150 151 152 153 154 155

  /// Create a text button from a pair of widgets that serve as the button's
  /// [icon] and [label].
  ///
  /// The icon and label are arranged in a row and padded by 12 logical pixels
  /// at the start, and 16 at the end, with an 8 pixel gap in between.
  ///
156
  /// The [icon], [label], and [clipBehavior] arguments must not be null.
157
  factory FlatButton.icon({
158
    Key key,
159
    @required VoidCallback onPressed,
160
    VoidCallback onLongPress,
161 162 163 164 165 166
    ValueChanged<bool> onHighlightChanged,
    ButtonTextTheme textTheme,
    Color textColor,
    Color disabledTextColor,
    Color color,
    Color disabledColor,
167 168
    Color focusColor,
    Color hoverColor,
169 170 171 172 173 174
    Color highlightColor,
    Color splashColor,
    Brightness colorBrightness,
    EdgeInsetsGeometry padding,
    ShapeBorder shape,
    Clip clipBehavior,
175
    FocusNode focusNode,
176
    bool autofocus,
177
    MaterialTapTargetSize materialTapTargetSize,
178 179
    @required Widget icon,
    @required Widget label,
180
  }) = _FlatButtonWithIcon;
181

182
  @override
183
  Widget build(BuildContext context) {
184 185
    final ThemeData theme = Theme.of(context);
    final ButtonThemeData buttonTheme = ButtonTheme.of(context);
186
    return RawMaterialButton(
187
      onPressed: onPressed,
188
      onLongPress: onLongPress,
189
      onHighlightChanged: onHighlightChanged,
190 191
      fillColor: buttonTheme.getFillColor(this),
      textStyle: theme.textTheme.button.copyWith(color: buttonTheme.getTextColor(this)),
192 193
      focusColor: buttonTheme.getFocusColor(this),
      hoverColor: buttonTheme.getHoverColor(this),
194 195 196
      highlightColor: buttonTheme.getHighlightColor(this),
      splashColor: buttonTheme.getSplashColor(this),
      elevation: buttonTheme.getElevation(this),
197 198
      focusElevation: buttonTheme.getFocusElevation(this),
      hoverElevation: buttonTheme.getHoverElevation(this),
199 200 201 202 203
      highlightElevation: buttonTheme.getHighlightElevation(this),
      disabledElevation: buttonTheme.getDisabledElevation(this),
      padding: buttonTheme.getPadding(this),
      constraints: buttonTheme.getConstraints(this),
      shape: buttonTheme.getShape(this),
204
      clipBehavior: clipBehavior,
205
      focusNode: focusNode,
206
      autofocus: autofocus,
207
      materialTapTargetSize: buttonTheme.getMaterialTapTargetSize(this),
208
      animationDuration: buttonTheme.getAnimationDuration(this),
209
      child: child,
210
    );
211 212
  }
}
213

Shi-Hao Hong's avatar
Shi-Hao Hong committed
214
/// The type of FlatButtons created with [FlatButton.icon].
215 216 217
///
/// This class only exists to give FlatButtons created with [FlatButton.icon]
/// a distinct class for the sake of [ButtonTheme]. It can not be instantiated.
218
class _FlatButtonWithIcon extends FlatButton with MaterialButtonWithIconMixin {
219 220 221
  _FlatButtonWithIcon({
    Key key,
    @required VoidCallback onPressed,
222
    VoidCallback onLongPress,
223 224 225 226 227 228
    ValueChanged<bool> onHighlightChanged,
    ButtonTextTheme textTheme,
    Color textColor,
    Color disabledTextColor,
    Color color,
    Color disabledColor,
229 230
    Color focusColor,
    Color hoverColor,
231 232 233 234 235
    Color highlightColor,
    Color splashColor,
    Brightness colorBrightness,
    EdgeInsetsGeometry padding,
    ShapeBorder shape,
236
    Clip clipBehavior = Clip.none,
237
    FocusNode focusNode,
238
    bool autofocus = false,
239 240 241 242 243
    MaterialTapTargetSize materialTapTargetSize,
    @required Widget icon,
    @required Widget label,
  }) : assert(icon != null),
       assert(label != null),
244
       assert(clipBehavior != null),
245
       assert(autofocus != null),
246 247 248
       super(
         key: key,
         onPressed: onPressed,
249
         onLongPress: onLongPress,
250 251 252 253 254 255
         onHighlightChanged: onHighlightChanged,
         textTheme: textTheme,
         textColor: textColor,
         disabledTextColor: disabledTextColor,
         color: color,
         disabledColor: disabledColor,
256 257
         focusColor: focusColor,
         hoverColor: hoverColor,
258 259 260 261 262 263
         highlightColor: highlightColor,
         splashColor: splashColor,
         colorBrightness: colorBrightness,
         padding: padding,
         shape: shape,
         clipBehavior: clipBehavior,
264
         focusNode: focusNode,
265
         autofocus: autofocus,
266 267 268 269 270 271 272 273 274 275 276 277
         materialTapTargetSize: materialTapTargetSize,
         child: Row(
           mainAxisSize: MainAxisSize.min,
           children: <Widget>[
             icon,
             const SizedBox(width: 8.0),
             label,
           ],
         ),
       );

}