| // 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. |
| |
| import 'package:flutter/foundation.dart'; |
| import 'package:flutter/widgets.dart'; |
| |
| import 'button.dart'; |
| import 'button_theme.dart'; |
| import 'material_button.dart'; |
| import 'theme.dart'; |
| import 'theme_data.dart'; |
| |
| /// A material design "raised button". |
| /// |
| /// A raised button is based on a [Material] widget whose [Material.elevation] |
| /// increases when the button is pressed. |
| /// |
| /// Use raised buttons to add dimension to otherwise mostly flat layouts, e.g. |
| /// in long busy lists of content, or in wide spaces. Avoid using raised buttons |
| /// on already-raised content such as dialogs or cards. |
| /// |
| /// If the [onPressed] callback is null, then the button will be disabled and by |
| /// default will resemble a flat button in the [disabledColor]. 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. |
| /// |
| /// If you want an ink-splash effect for taps, but don't want to use a button, |
| /// consider using [InkWell] directly. |
| /// |
| /// Raised buttons have a minimum size of 88.0 by 36.0 which can be overridden |
| /// with [ButtonTheme]. |
| /// |
| /// {@tool snippet --template=stateless_widget_scaffold} |
| /// |
| /// This sample shows how to render a disabled RaisedButton, an enabled RaisedButton |
| /// and lastly a RaisedButton with gradient background. |
| /// |
| /// ```dart |
| /// Widget build(BuildContext context) { |
| /// return Scaffold( |
| /// body: Center( |
| /// child: Column( |
| /// mainAxisSize: MainAxisSize.min, |
| /// children: <Widget>[ |
| /// RaisedButton( |
| /// onPressed: null, |
| /// child: const Text('Disabled Button'), |
| /// ), |
| /// RaisedButton( |
| /// onPressed: () {}, |
| /// child: const Text('Enabled Button'), |
| /// ), |
| /// RaisedButton( |
| /// onPressed: () {}, |
| /// textColor: Colors.white, |
| /// padding: const EdgeInsets.all(0.0), |
| /// child: Container( |
| /// decoration: const BoxDecoration( |
| /// gradient: LinearGradient( |
| /// colors: <Color>[Colors.red, Colors.green, Colors.blue], |
| /// ), |
| /// ), |
| /// padding: const EdgeInsets.all(10.0), |
| /// child: Text('Gradient Button'), |
| /// ), |
| /// ), |
| /// ], |
| /// ), |
| /// ), |
| /// ); |
| /// } |
| /// ``` |
| /// {@end-tool} |
| /// |
| /// See also: |
| /// |
| /// * [FlatButton], a material design button without a shadow. |
| /// * [DropdownButton], a button that shows options to select from. |
| /// * [FloatingActionButton], the round button in material applications. |
| /// * [IconButton], to create buttons that just contain icons. |
| /// * [InkWell], which implements the ink splash part of a flat button. |
| /// * [RawMaterialButton], the widget this widget is based on. |
| /// * <https://material.io/design/components/buttons.html> |
| class RaisedButton extends MaterialButton { |
| /// Create a filled button. |
| /// |
| /// The [elevation], [highlightElevation], [disabledElevation], and |
| /// [clipBehavior] arguments must not be null. Additionally, [elevation], |
| /// [highlightElevation], and [disabledElevation] must be non-negative. |
| const RaisedButton({ |
| Key key, |
| @required VoidCallback onPressed, |
| ValueChanged<bool> onHighlightChanged, |
| ButtonTextTheme textTheme, |
| Color textColor, |
| Color disabledTextColor, |
| Color color, |
| Color disabledColor, |
| Color highlightColor, |
| Color splashColor, |
| Brightness colorBrightness, |
| double elevation, |
| double highlightElevation, |
| double disabledElevation, |
| EdgeInsetsGeometry padding, |
| ShapeBorder shape, |
| Clip clipBehavior = Clip.none, |
| MaterialTapTargetSize materialTapTargetSize, |
| Duration animationDuration, |
| Widget child, |
| }) : assert(elevation == null || elevation >= 0.0), |
| assert(highlightElevation == null || highlightElevation >= 0.0), |
| assert(disabledElevation == null || disabledElevation >= 0.0), |
| super( |
| key: key, |
| onPressed: onPressed, |
| onHighlightChanged: onHighlightChanged, |
| textTheme: textTheme, |
| textColor: textColor, |
| disabledTextColor: disabledTextColor, |
| color: color, |
| disabledColor: disabledColor, |
| highlightColor: highlightColor, |
| splashColor: splashColor, |
| colorBrightness: colorBrightness, |
| elevation: elevation, |
| highlightElevation: highlightElevation, |
| disabledElevation: disabledElevation, |
| padding: padding, |
| shape: shape, |
| clipBehavior: clipBehavior, |
| materialTapTargetSize: materialTapTargetSize, |
| animationDuration: animationDuration, |
| child: child, |
| ); |
| |
| /// Create a filled 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. |
| /// |
| /// The [elevation], [highlightElevation], [disabledElevation], [icon], |
| /// [label], and [clipBehavior] arguments must not be null. |
| factory RaisedButton.icon({ |
| Key key, |
| @required VoidCallback onPressed, |
| ValueChanged<bool> onHighlightChanged, |
| ButtonTextTheme textTheme, |
| Color textColor, |
| Color disabledTextColor, |
| Color color, |
| Color disabledColor, |
| Color highlightColor, |
| Color splashColor, |
| Brightness colorBrightness, |
| double elevation, |
| double highlightElevation, |
| double disabledElevation, |
| ShapeBorder shape, |
| Clip clipBehavior, |
| MaterialTapTargetSize materialTapTargetSize, |
| Duration animationDuration, |
| @required Widget icon, |
| @required Widget label, |
| }) = _RaisedButtonWithIcon; |
| |
| @override |
| Widget build(BuildContext context) { |
| final ThemeData theme = Theme.of(context); |
| final ButtonThemeData buttonTheme = ButtonTheme.of(context); |
| return RawMaterialButton( |
| onPressed: onPressed, |
| onHighlightChanged: onHighlightChanged, |
| clipBehavior: clipBehavior ?? Clip.none, |
| fillColor: buttonTheme.getFillColor(this), |
| textStyle: theme.textTheme.button.copyWith(color: buttonTheme.getTextColor(this)), |
| highlightColor: buttonTheme.getHighlightColor(this), |
| splashColor: buttonTheme.getSplashColor(this), |
| elevation: buttonTheme.getElevation(this), |
| highlightElevation: buttonTheme.getHighlightElevation(this), |
| disabledElevation: buttonTheme.getDisabledElevation(this), |
| padding: buttonTheme.getPadding(this), |
| constraints: buttonTheme.getConstraints(this), |
| shape: buttonTheme.getShape(this), |
| animationDuration: buttonTheme.getAnimationDuration(this), |
| materialTapTargetSize: buttonTheme.getMaterialTapTargetSize(this), |
| child: child, |
| ); |
| } |
| |
| @override |
| void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
| super.debugFillProperties(properties); |
| properties.add(ObjectFlagProperty<VoidCallback>('onPressed', onPressed, ifNull: 'disabled')); |
| properties.add(DiagnosticsProperty<Color>('textColor', textColor, defaultValue: null)); |
| properties.add(DiagnosticsProperty<Color>('disabledTextColor', disabledTextColor, defaultValue: null)); |
| properties.add(DiagnosticsProperty<Color>('color', color, defaultValue: null)); |
| properties.add(DiagnosticsProperty<Color>('disabledColor', disabledColor, defaultValue: null)); |
| properties.add(DiagnosticsProperty<Color>('highlightColor', highlightColor, defaultValue: null)); |
| properties.add(DiagnosticsProperty<Color>('splashColor', splashColor, defaultValue: null)); |
| properties.add(DiagnosticsProperty<Brightness>('colorBrightness', colorBrightness, defaultValue: null)); |
| properties.add(DiagnosticsProperty<double>('elevation', elevation, defaultValue: null)); |
| properties.add(DiagnosticsProperty<double>('highlightElevation', highlightElevation, defaultValue: null)); |
| properties.add(DiagnosticsProperty<double>('disabledElevation', disabledElevation, defaultValue: null)); |
| properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding, defaultValue: null)); |
| properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null)); |
| } |
| } |
| |
| /// The type of of RaisedButtons created with [RaisedButton.icon]. |
| /// |
| /// This class only exists to give RaisedButtons created with [RaisedButton.icon] |
| /// a distinct class for the sake of [ButtonTheme]. It can not be instantiated. |
| class _RaisedButtonWithIcon extends RaisedButton with MaterialButtonWithIconMixin { |
| _RaisedButtonWithIcon({ |
| Key key, |
| @required VoidCallback onPressed, |
| ValueChanged<bool> onHighlightChanged, |
| ButtonTextTheme textTheme, |
| Color textColor, |
| Color disabledTextColor, |
| Color color, |
| Color disabledColor, |
| Color highlightColor, |
| Color splashColor, |
| Brightness colorBrightness, |
| double elevation, |
| double highlightElevation, |
| double disabledElevation, |
| ShapeBorder shape, |
| Clip clipBehavior = Clip.none, |
| MaterialTapTargetSize materialTapTargetSize, |
| Duration animationDuration, |
| @required Widget icon, |
| @required Widget label, |
| }) : assert(elevation == null || elevation >= 0.0), |
| assert(highlightElevation == null || highlightElevation >= 0.0), |
| assert(disabledElevation == null || disabledElevation >= 0.0), |
| assert(icon != null), |
| assert(label != null), |
| super( |
| key: key, |
| onPressed: onPressed, |
| onHighlightChanged: onHighlightChanged, |
| textTheme: textTheme, |
| textColor: textColor, |
| disabledTextColor: disabledTextColor, |
| color: color, |
| disabledColor: disabledColor, |
| highlightColor: highlightColor, |
| splashColor: splashColor, |
| colorBrightness: colorBrightness, |
| elevation: elevation, |
| highlightElevation: highlightElevation, |
| disabledElevation: disabledElevation, |
| shape: shape, |
| clipBehavior: clipBehavior, |
| materialTapTargetSize: materialTapTargetSize, |
| animationDuration: animationDuration, |
| child: Row( |
| mainAxisSize: MainAxisSize.min, |
| children: <Widget>[ |
| icon, |
| const SizedBox(width: 8.0), |
| label, |
| ], |
| ), |
| ); |
| } |