mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
This reverts commit c689c97d0579d2a215034359a3cbcdc61173d2ab. The Dart analyzer in Google3 has been upgraded so we won't need this.
286 lines
9.6 KiB
Dart
286 lines
9.6 KiB
Dart
// Copyright 2018 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/rendering.dart';
|
|
import 'package:flutter/widgets.dart';
|
|
|
|
import 'button.dart';
|
|
import 'button_theme.dart';
|
|
import 'constants.dart';
|
|
import 'ink_well.dart';
|
|
import 'material.dart';
|
|
import 'theme.dart';
|
|
import 'theme_data.dart';
|
|
|
|
/// A utility class for building Material buttons that depend on the
|
|
/// ambient [ButtonTheme] and [Theme].
|
|
///
|
|
/// The button's size will expand to fit the child widget, if necessary.
|
|
///
|
|
/// MaterialButtons whose [onPressed] handler is null will be disabled. To have
|
|
/// an enabled button, make sure to pass a non-null value for onPressed.
|
|
///
|
|
/// Rather than using this class directly, consider using [FlatButton],
|
|
/// OutlineButton, or [RaisedButton], which configure this class with
|
|
/// appropriate defaults that match the material design specification.
|
|
///
|
|
/// To create a button directly, without inheriting theme defaults, use
|
|
/// [RawMaterialButton].
|
|
///
|
|
/// If you want an ink-splash effect for taps, but don't want to use a button,
|
|
/// consider using [InkWell] directly.
|
|
///
|
|
/// See also:
|
|
///
|
|
/// * [IconButton], to create buttons that contain icons rather than text.
|
|
class MaterialButton extends StatelessWidget {
|
|
/// Creates a material button.
|
|
///
|
|
/// Rather than creating a material button directly, consider using
|
|
/// [FlatButton] or [RaisedButton]. To create a custom Material button
|
|
/// consider using [RawMaterialButton].
|
|
///
|
|
/// The [clipBehavior] argument must not be null.
|
|
const MaterialButton({
|
|
Key key,
|
|
@required this.onPressed,
|
|
this.onHighlightChanged,
|
|
this.textTheme,
|
|
this.textColor,
|
|
this.disabledTextColor,
|
|
this.color,
|
|
this.disabledColor,
|
|
this.highlightColor,
|
|
this.splashColor,
|
|
this.colorBrightness,
|
|
this.elevation,
|
|
this.highlightElevation,
|
|
this.disabledElevation,
|
|
this.padding,
|
|
this.shape,
|
|
this.clipBehavior = Clip.none,
|
|
this.materialTapTargetSize,
|
|
this.animationDuration,
|
|
this.minWidth,
|
|
this.height,
|
|
this.child,
|
|
}) : super(key: key);
|
|
|
|
/// The callback that is called when the button is tapped or otherwise activated.
|
|
///
|
|
/// If this is set to null, the button will be disabled.
|
|
final VoidCallback onPressed;
|
|
|
|
/// Called by the underlying [InkWell] widget's [InkWell.onHighlightChanged]
|
|
/// callback.
|
|
final ValueChanged<bool> onHighlightChanged;
|
|
|
|
/// Defines the button's base colors, and the defaults for the button's minimum
|
|
/// size, internal padding, and shape.
|
|
///
|
|
/// Defaults to `ButtonTheme.of(context).textTheme`.
|
|
final ButtonTextTheme textTheme;
|
|
|
|
/// The color to use for this button's text.
|
|
///
|
|
/// The button's [Material.textStyle] will be the current theme's button
|
|
/// text style, [ThemeData.textTheme.button], configured with this color.
|
|
///
|
|
/// The default text color depends on the button theme's text theme,
|
|
/// [ButtonThemeData.textTheme].
|
|
///
|
|
/// See also:
|
|
/// * [disabledTextColor], the text color to use when the button has been
|
|
/// disabled.
|
|
final Color textColor;
|
|
|
|
/// The color to use for this button's text when the button is disabled.
|
|
///
|
|
/// The button's [Material.textStyle] will be the current theme's button
|
|
/// text style, [ThemeData.textTheme.button], configured with this color.
|
|
///
|
|
/// The default value is the theme's disabled color,
|
|
/// [ThemeData.disabledColor].
|
|
///
|
|
/// See also:
|
|
/// * [textColor] - The color to use for this button's text when the button is [enabled].
|
|
final Color disabledTextColor;
|
|
|
|
/// The button's fill color, displayed by its [Material], while it
|
|
/// is in its default (unpressed, [enabled]) state.
|
|
///
|
|
/// The default fill color is the theme's button color, [ThemeData.buttonColor].
|
|
///
|
|
/// See also:
|
|
/// * [disabledColor] - the fill color of the button when the button is disabled.
|
|
final Color color;
|
|
|
|
/// The fill color of the button when the button is disabled.
|
|
///
|
|
/// The default value of this color is the theme's disabled color,
|
|
/// [ThemeData.disabledColor].
|
|
///
|
|
/// See also:
|
|
/// * [color] - the fill color of the button when the button is [enabled].
|
|
final Color disabledColor;
|
|
|
|
/// The splash color of the button's [InkWell].
|
|
///
|
|
/// The ink splash indicates that the button has been touched. It
|
|
/// appears on top of the button's child and spreads in an expanding
|
|
/// circle beginning where the touch occurred.
|
|
///
|
|
/// The default splash color is the current theme's splash color,
|
|
/// [ThemeData.splashColor].
|
|
///
|
|
/// The appearance of the splash can be configured with the theme's splash
|
|
/// factory, [ThemeData.splashFactory].
|
|
final Color splashColor;
|
|
|
|
/// The highlight color of the button's [InkWell].
|
|
///
|
|
/// The highlight indicates that the button is actively being pressed. It
|
|
/// appears on top of the button's child and quickly spreads to fill
|
|
/// the button, and then fades out.
|
|
///
|
|
/// If [textTheme] is [ButtonTextTheme.primary], the default highlight color is
|
|
/// transparent (in other words the highlight doesn't appear). Otherwise it's
|
|
/// the current theme's highlight color, [ThemeData.highlightColor].
|
|
final Color highlightColor;
|
|
|
|
/// The z-coordinate at which to place this button. This controls the size of
|
|
/// the shadow below the raised button.
|
|
///
|
|
/// Defaults to 2, the appropriate elevation for raised buttons.
|
|
///
|
|
/// See also:
|
|
///
|
|
/// * [FlatButton], a button with no elevation or fill color.
|
|
/// * [disabledElevation], the elevation when the button is disabled.
|
|
/// * [highlightElevation], the elevation when the button is pressed.
|
|
final double elevation;
|
|
|
|
/// The elevation for the button's [Material] when the button
|
|
/// is [enabled] and pressed.
|
|
///
|
|
/// This controls the size of the shadow below the button. When a tap
|
|
/// down gesture occurs within the button, its [InkWell] displays a
|
|
/// [highlightColor] "highlight".
|
|
///
|
|
/// Defaults to 8.0.
|
|
///
|
|
/// See also:
|
|
///
|
|
/// * [elevation], the default elevation.
|
|
/// * [disabledElevation], the elevation when the button is disabled.
|
|
final double highlightElevation;
|
|
|
|
/// The elevation for the button's [Material] when the button
|
|
/// is not [enabled].
|
|
///
|
|
/// Defaults to 0.0.
|
|
///
|
|
/// See also:
|
|
///
|
|
/// * [elevation], the default elevation.
|
|
/// * [highlightElevation], the elevation when the button is pressed.
|
|
final double disabledElevation;
|
|
|
|
/// The theme brightness to use for this button.
|
|
///
|
|
/// Defaults to the theme's brightness, [ThemeData.brightness].
|
|
final Brightness colorBrightness;
|
|
|
|
/// The button's label.
|
|
///
|
|
/// Often a [Text] widget in all caps.
|
|
final Widget child;
|
|
|
|
/// Whether the button is enabled or disabled.
|
|
///
|
|
/// Buttons are disabled by default. To enable a button, set its [onPressed]
|
|
/// property to a non-null value.
|
|
bool get enabled => onPressed != null;
|
|
|
|
/// The internal padding for the button's [child].
|
|
///
|
|
/// Defaults to the value from the current [ButtonTheme],
|
|
/// [ButtonThemeData.padding].
|
|
final EdgeInsetsGeometry padding;
|
|
|
|
/// The shape of the button's [Material].
|
|
///
|
|
/// The button's highlight and splash are clipped to this shape. If the
|
|
/// button has an elevation, then its drop shadow is defined by this
|
|
/// shape as well.
|
|
final ShapeBorder shape;
|
|
|
|
/// {@macro flutter.widgets.Clip}
|
|
final Clip clipBehavior;
|
|
|
|
/// Defines the duration of animated changes for [shape] and [elevation].
|
|
///
|
|
/// The default value is [kThemeChangeDuration].
|
|
final Duration animationDuration;
|
|
|
|
/// Configures the minimum size of the tap target.
|
|
///
|
|
/// Defaults to [ThemeData.materialTapTargetSize].
|
|
///
|
|
/// See also:
|
|
///
|
|
/// * [MaterialTapTargetSize], for a description of how this affects tap targets.
|
|
final MaterialTapTargetSize materialTapTargetSize;
|
|
|
|
/// The smallest horizontal extent that the button will occupy.
|
|
///
|
|
/// Defaults to the value from the current [ButtonTheme].
|
|
final double minWidth;
|
|
|
|
/// The vertical extent of the button.
|
|
///
|
|
/// Defaults to the value from the current [ButtonTheme].
|
|
final double height;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final ThemeData theme = Theme.of(context);
|
|
final ButtonThemeData buttonTheme = ButtonTheme.of(context);
|
|
|
|
return RawMaterialButton(
|
|
onPressed: onPressed,
|
|
fillColor: color,
|
|
textStyle: theme.textTheme.button.copyWith(color: buttonTheme.getTextColor(this)),
|
|
highlightColor: highlightColor ?? theme.highlightColor,
|
|
splashColor: splashColor ?? theme.splashColor,
|
|
elevation: buttonTheme.getElevation(this),
|
|
highlightElevation: buttonTheme.getHighlightElevation(this),
|
|
padding: buttonTheme.getPadding(this),
|
|
constraints: buttonTheme.getConstraints(this).copyWith(
|
|
minWidth: minWidth,
|
|
minHeight: height,
|
|
),
|
|
shape: buttonTheme.shape,
|
|
clipBehavior: clipBehavior ?? Clip.none,
|
|
animationDuration: buttonTheme.getAnimationDuration(this),
|
|
child: child,
|
|
materialTapTargetSize: materialTapTargetSize ?? theme.materialTapTargetSize,
|
|
);
|
|
}
|
|
|
|
@override
|
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
|
super.debugFillProperties(properties);
|
|
properties.add(FlagProperty('enabled', value: enabled, ifFalse: 'disabled'));
|
|
}
|
|
}
|
|
|
|
/// The type of [MaterialButton]s created with [RaisedButton.icon], [FlatButton.icon],
|
|
/// and [OutlineButton.icon].
|
|
///
|
|
/// This mixin only exists to give the "label and icon" button widgets a distinct
|
|
/// type for the sake of [ButtonTheme].
|
|
mixin MaterialButtonWithIconMixin { }
|