forked from firka/flutter
Add autofocus parameter to widgets which use Focus widget internally (#37809)
Add an autofocus parameter to widgets which use Focus widget internally, and update related docs. This will allow developers to request that a particular widget be automatically focused when shown.
This commit is contained in:
@@ -160,7 +160,7 @@ class _CupertinoTextFieldSelectionGestureDetectorBuilder extends TextSelectionGe
|
||||
/// Design UI conventions.
|
||||
/// * [EditableText], which is the raw text editing control at the heart of a
|
||||
/// [TextField].
|
||||
/// * Learn how to use a [TextEditingController] in one of our [cookbook recipe]s.(https://flutter.dev/docs/cookbook/forms/text-field-changes#2-use-a-texteditingcontroller)
|
||||
/// * Learn how to use a [TextEditingController] in one of our [cookbook recipes](https://flutter.dev/docs/cookbook/forms/text-field-changes#2-use-a-texteditingcontroller).
|
||||
class CupertinoTextField extends StatefulWidget {
|
||||
/// Creates an iOS-style text field.
|
||||
///
|
||||
@@ -179,6 +179,13 @@ class CupertinoTextField extends StatefulWidget {
|
||||
/// The text cursor is not shown if [showCursor] is false or if [showCursor]
|
||||
/// is null (the default) and [readOnly] is true.
|
||||
///
|
||||
/// If specified, the [maxLength] property must be greater than zero.
|
||||
///
|
||||
/// The [autocorrect], [autofocus], [clearButtonMode], [dragStartBehavior],
|
||||
/// [expands], [maxLengthEnforced], [obscureText], [prefixMode], [readOnly],
|
||||
/// [scrollPadding], [suffixMode], and [textAlign] properties must not be
|
||||
/// null.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [minLines]
|
||||
@@ -276,9 +283,7 @@ class CupertinoTextField extends StatefulWidget {
|
||||
/// If null, this widget will create its own [TextEditingController].
|
||||
final TextEditingController controller;
|
||||
|
||||
/// Controls whether this widget has keyboard focus.
|
||||
///
|
||||
/// If null, this widget will create its own [FocusNode].
|
||||
/// {@macro flutter.widgets.Focus.focusNode}
|
||||
final FocusNode focusNode;
|
||||
|
||||
/// Controls the [BoxDecoration] of the box behind the text input.
|
||||
|
||||
@@ -31,9 +31,9 @@ class RawMaterialButton extends StatefulWidget {
|
||||
/// Create a button based on [Semantics], [Material], and [InkWell] widgets.
|
||||
///
|
||||
/// The [shape], [elevation], [focusElevation], [hoverElevation],
|
||||
/// [highlightElevation], [disabledElevation], [padding], [constraints], and
|
||||
/// [clipBehavior] arguments must not be null. Additionally, [elevation],
|
||||
/// [focusElevation], [hoverElevation], [highlightElevation], and
|
||||
/// [highlightElevation], [disabledElevation], [padding], [constraints],
|
||||
/// [autofocus], and [clipBehavior] arguments must not be null. Additionally,
|
||||
/// [elevation], [focusElevation], [hoverElevation], [highlightElevation], and
|
||||
/// [disabledElevation] must be non-negative.
|
||||
const RawMaterialButton({
|
||||
Key key,
|
||||
@@ -56,6 +56,7 @@ class RawMaterialButton extends StatefulWidget {
|
||||
this.animationDuration = kThemeChangeDuration,
|
||||
this.clipBehavior = Clip.none,
|
||||
this.focusNode,
|
||||
this.autofocus = false,
|
||||
MaterialTapTargetSize materialTapTargetSize,
|
||||
this.child,
|
||||
}) : materialTapTargetSize = materialTapTargetSize ?? MaterialTapTargetSize.padded,
|
||||
@@ -69,6 +70,7 @@ class RawMaterialButton extends StatefulWidget {
|
||||
assert(constraints != null),
|
||||
assert(animationDuration != null),
|
||||
assert(clipBehavior != null),
|
||||
assert(autofocus != null),
|
||||
super(key: key);
|
||||
|
||||
/// Called when the button is tapped or otherwise activated.
|
||||
@@ -232,14 +234,12 @@ class RawMaterialButton extends StatefulWidget {
|
||||
/// * [MaterialTapTargetSize], for a description of how this affects tap targets.
|
||||
final MaterialTapTargetSize materialTapTargetSize;
|
||||
|
||||
/// An optional focus node to use for requesting focus when pressed.
|
||||
///
|
||||
/// If not supplied, the button will create and host its own [FocusNode].
|
||||
///
|
||||
/// If supplied, the given focusNode will be _hosted_ by this widget. See
|
||||
/// [FocusNode] for more information on what that implies.
|
||||
/// {@macro flutter.widgets.Focus.focusNode}
|
||||
final FocusNode focusNode;
|
||||
|
||||
/// {@macro flutter.widgets.Focus.autofocus}
|
||||
final bool autofocus;
|
||||
|
||||
/// {@macro flutter.widgets.Clip}
|
||||
final Clip clipBehavior;
|
||||
|
||||
@@ -331,6 +331,7 @@ class _RawMaterialButtonState extends State<RawMaterialButton> {
|
||||
final Widget result = Focus(
|
||||
focusNode: widget.focusNode,
|
||||
onFocusChange: _handleFocusedChanged,
|
||||
autofocus: widget.autofocus,
|
||||
child: ConstrainedBox(
|
||||
constraints: widget.constraints,
|
||||
child: Material(
|
||||
|
||||
@@ -98,6 +98,12 @@ abstract class ChipAttributes {
|
||||
/// {@macro flutter.widgets.Clip}
|
||||
Clip get clipBehavior;
|
||||
|
||||
/// {@macro flutter.widgets.Focus.focusNode}
|
||||
FocusNode get focusNode;
|
||||
|
||||
/// {@macro flutter.widgets.Focus.autofocus}
|
||||
bool get autofocus;
|
||||
|
||||
/// Color to be used for the unselected, enabled chip's background.
|
||||
///
|
||||
/// The default is light grey.
|
||||
@@ -493,7 +499,7 @@ abstract class TappableChipAttributes {
|
||||
class Chip extends StatelessWidget implements ChipAttributes, DeletableChipAttributes {
|
||||
/// Creates a material design chip.
|
||||
///
|
||||
/// The [label] and [clipBehavior] arguments must not be null.
|
||||
/// The [label], [autofocus], and [clipBehavior] arguments must not be null.
|
||||
/// The [elevation] must be null or non-negative.
|
||||
const Chip({
|
||||
Key key,
|
||||
@@ -507,12 +513,15 @@ class Chip extends StatelessWidget implements ChipAttributes, DeletableChipAttri
|
||||
this.deleteButtonTooltipMessage,
|
||||
this.shape,
|
||||
this.clipBehavior = Clip.none,
|
||||
this.focusNode,
|
||||
this.autofocus = false,
|
||||
this.backgroundColor,
|
||||
this.padding,
|
||||
this.materialTapTargetSize,
|
||||
this.elevation,
|
||||
this.shadowColor,
|
||||
}) : assert(label != null),
|
||||
assert(autofocus != null),
|
||||
assert(clipBehavior != null),
|
||||
assert(elevation == null || elevation >= 0.0),
|
||||
super(key: key);
|
||||
@@ -530,6 +539,10 @@ class Chip extends StatelessWidget implements ChipAttributes, DeletableChipAttri
|
||||
@override
|
||||
final Clip clipBehavior;
|
||||
@override
|
||||
final FocusNode focusNode;
|
||||
@override
|
||||
final bool autofocus;
|
||||
@override
|
||||
final Color backgroundColor;
|
||||
@override
|
||||
final EdgeInsetsGeometry padding;
|
||||
@@ -563,6 +576,8 @@ class Chip extends StatelessWidget implements ChipAttributes, DeletableChipAttri
|
||||
tapEnabled: false,
|
||||
shape: shape,
|
||||
clipBehavior: clipBehavior,
|
||||
focusNode: focusNode,
|
||||
autofocus: autofocus,
|
||||
backgroundColor: backgroundColor,
|
||||
padding: padding,
|
||||
materialTapTargetSize: materialTapTargetSize,
|
||||
@@ -630,9 +645,10 @@ class InputChip extends StatelessWidget
|
||||
/// The [onPressed] and [onSelected] callbacks must not both be specified at
|
||||
/// the same time.
|
||||
///
|
||||
/// The [label], [isEnabled], [selected], and [clipBehavior] arguments must
|
||||
/// not be null. The [pressElevation] and [elevation] must be null or
|
||||
/// non-negative. Typically, [pressElevation] is greater than [elevation].
|
||||
/// The [label], [isEnabled], [selected], [autofocus], and [clipBehavior]
|
||||
/// arguments must not be null. The [pressElevation] and [elevation] must be
|
||||
/// null or non-negative. Typically, [pressElevation] is greater than
|
||||
/// [elevation].
|
||||
const InputChip({
|
||||
Key key,
|
||||
this.avatar,
|
||||
@@ -653,6 +669,8 @@ class InputChip extends StatelessWidget
|
||||
this.tooltip,
|
||||
this.shape,
|
||||
this.clipBehavior = Clip.none,
|
||||
this.focusNode,
|
||||
this.autofocus = false,
|
||||
this.backgroundColor,
|
||||
this.padding,
|
||||
this.materialTapTargetSize,
|
||||
@@ -664,6 +682,7 @@ class InputChip extends StatelessWidget
|
||||
assert(isEnabled != null),
|
||||
assert(label != null),
|
||||
assert(clipBehavior != null),
|
||||
assert(autofocus != null),
|
||||
assert(pressElevation == null || pressElevation >= 0.0),
|
||||
assert(elevation == null || elevation >= 0.0),
|
||||
super(key: key);
|
||||
@@ -705,6 +724,10 @@ class InputChip extends StatelessWidget
|
||||
@override
|
||||
final Clip clipBehavior;
|
||||
@override
|
||||
final FocusNode focusNode;
|
||||
@override
|
||||
final bool autofocus;
|
||||
@override
|
||||
final Color backgroundColor;
|
||||
@override
|
||||
final EdgeInsetsGeometry padding;
|
||||
@@ -741,6 +764,8 @@ class InputChip extends StatelessWidget
|
||||
tooltip: tooltip,
|
||||
shape: shape,
|
||||
clipBehavior: clipBehavior,
|
||||
focusNode: focusNode,
|
||||
autofocus: autofocus,
|
||||
backgroundColor: backgroundColor,
|
||||
padding: padding,
|
||||
materialTapTargetSize: materialTapTargetSize,
|
||||
@@ -814,9 +839,9 @@ class ChoiceChip extends StatelessWidget
|
||||
DisabledChipAttributes {
|
||||
/// Create a chip that acts like a radio button.
|
||||
///
|
||||
/// The [label], [selected], and [clipBehavior] arguments must not be null.
|
||||
/// The [pressElevation] and [elevation] must be null or non-negative.
|
||||
/// Typically, [pressElevation] is greater than [elevation].
|
||||
/// The [label], [selected], [autofocus], and [clipBehavior] arguments must
|
||||
/// not be null. The [pressElevation] and [elevation] must be null or
|
||||
/// non-negative. Typically, [pressElevation] is greater than [elevation].
|
||||
const ChoiceChip({
|
||||
Key key,
|
||||
this.avatar,
|
||||
@@ -831,6 +856,8 @@ class ChoiceChip extends StatelessWidget
|
||||
this.tooltip,
|
||||
this.shape,
|
||||
this.clipBehavior = Clip.none,
|
||||
this.focusNode,
|
||||
this.autofocus = false,
|
||||
this.backgroundColor,
|
||||
this.padding,
|
||||
this.materialTapTargetSize,
|
||||
@@ -841,6 +868,7 @@ class ChoiceChip extends StatelessWidget
|
||||
}) : assert(selected != null),
|
||||
assert(label != null),
|
||||
assert(clipBehavior != null),
|
||||
assert(autofocus != null),
|
||||
assert(pressElevation == null || pressElevation >= 0.0),
|
||||
assert(elevation == null || elevation >= 0.0),
|
||||
super(key: key);
|
||||
@@ -870,6 +898,10 @@ class ChoiceChip extends StatelessWidget
|
||||
@override
|
||||
final Clip clipBehavior;
|
||||
@override
|
||||
final FocusNode focusNode;
|
||||
@override
|
||||
final bool autofocus;
|
||||
@override
|
||||
final Color backgroundColor;
|
||||
@override
|
||||
final EdgeInsetsGeometry padding;
|
||||
@@ -904,6 +936,8 @@ class ChoiceChip extends StatelessWidget
|
||||
tooltip: tooltip,
|
||||
shape: shape,
|
||||
clipBehavior: clipBehavior,
|
||||
focusNode: focusNode,
|
||||
autofocus: autofocus,
|
||||
disabledColor: disabledColor,
|
||||
selectedColor: selectedColor ?? chipTheme.secondarySelectedColor,
|
||||
backgroundColor: backgroundColor,
|
||||
@@ -1011,9 +1045,9 @@ class FilterChip extends StatelessWidget
|
||||
DisabledChipAttributes {
|
||||
/// Create a chip that acts like a checkbox.
|
||||
///
|
||||
/// The [selected], [label], and [clipBehavior] arguments must not be null.
|
||||
/// The [pressElevation] and [elevation] must be null or non-negative.
|
||||
/// Typically, [pressElevation] is greater than [elevation].
|
||||
/// The [selected], [label], [autofocus], and [clipBehavior] arguments must
|
||||
/// not be null. The [pressElevation] and [elevation] must be null or
|
||||
/// non-negative. Typically, [pressElevation] is greater than [elevation].
|
||||
const FilterChip({
|
||||
Key key,
|
||||
this.avatar,
|
||||
@@ -1028,6 +1062,8 @@ class FilterChip extends StatelessWidget
|
||||
this.tooltip,
|
||||
this.shape,
|
||||
this.clipBehavior = Clip.none,
|
||||
this.focusNode,
|
||||
this.autofocus = false,
|
||||
this.backgroundColor,
|
||||
this.padding,
|
||||
this.materialTapTargetSize,
|
||||
@@ -1038,6 +1074,7 @@ class FilterChip extends StatelessWidget
|
||||
}) : assert(selected != null),
|
||||
assert(label != null),
|
||||
assert(clipBehavior != null),
|
||||
assert(autofocus != null),
|
||||
assert(pressElevation == null || pressElevation >= 0.0),
|
||||
assert(elevation == null || elevation >= 0.0),
|
||||
super(key: key);
|
||||
@@ -1067,6 +1104,10 @@ class FilterChip extends StatelessWidget
|
||||
@override
|
||||
final Clip clipBehavior;
|
||||
@override
|
||||
final FocusNode focusNode;
|
||||
@override
|
||||
final bool autofocus;
|
||||
@override
|
||||
final Color backgroundColor;
|
||||
@override
|
||||
final EdgeInsetsGeometry padding;
|
||||
@@ -1098,6 +1139,8 @@ class FilterChip extends StatelessWidget
|
||||
tooltip: tooltip,
|
||||
shape: shape,
|
||||
clipBehavior: clipBehavior,
|
||||
focusNode: focusNode,
|
||||
autofocus: autofocus,
|
||||
backgroundColor: backgroundColor,
|
||||
disabledColor: disabledColor,
|
||||
selectedColor: selectedColor,
|
||||
@@ -1162,9 +1205,9 @@ class FilterChip extends StatelessWidget
|
||||
class ActionChip extends StatelessWidget implements ChipAttributes, TappableChipAttributes {
|
||||
/// Create a chip that acts like a button.
|
||||
///
|
||||
/// The [label], [onPressed] and [clipBehavior] arguments must not be null.
|
||||
/// The [pressElevation] and [elevation] must be null or non-negative.
|
||||
/// Typically, [pressElevation] is greater than [elevation].
|
||||
/// The [label], [onPressed], [autofocus], and [clipBehavior] arguments must
|
||||
/// not be null. The [pressElevation] and [elevation] must be null or
|
||||
/// non-negative. Typically, [pressElevation] is greater than [elevation].
|
||||
const ActionChip({
|
||||
Key key,
|
||||
this.avatar,
|
||||
@@ -1176,12 +1219,15 @@ class ActionChip extends StatelessWidget implements ChipAttributes, TappableChip
|
||||
this.tooltip,
|
||||
this.shape,
|
||||
this.clipBehavior = Clip.none,
|
||||
this.focusNode,
|
||||
this.autofocus = false,
|
||||
this.backgroundColor,
|
||||
this.padding,
|
||||
this.materialTapTargetSize,
|
||||
this.elevation,
|
||||
this.shadowColor,
|
||||
}) : assert(label != null),
|
||||
assert(autofocus != null),
|
||||
assert(
|
||||
onPressed != null,
|
||||
'Rather than disabling an ActionChip by setting onPressed to null, '
|
||||
@@ -1210,6 +1256,10 @@ class ActionChip extends StatelessWidget implements ChipAttributes, TappableChip
|
||||
@override
|
||||
final Clip clipBehavior;
|
||||
@override
|
||||
final FocusNode focusNode;
|
||||
@override
|
||||
final bool autofocus;
|
||||
@override
|
||||
final Color backgroundColor;
|
||||
@override
|
||||
final EdgeInsetsGeometry padding;
|
||||
@@ -1233,6 +1283,8 @@ class ActionChip extends StatelessWidget implements ChipAttributes, TappableChip
|
||||
backgroundColor: backgroundColor,
|
||||
shape: shape,
|
||||
clipBehavior: clipBehavior,
|
||||
focusNode: focusNode,
|
||||
autofocus: autofocus,
|
||||
padding: padding,
|
||||
labelPadding: labelPadding,
|
||||
isEnabled: true,
|
||||
@@ -1285,9 +1337,10 @@ class RawChip extends StatefulWidget
|
||||
/// The [onPressed] and [onSelected] callbacks must not both be specified at
|
||||
/// the same time.
|
||||
///
|
||||
/// The [label], [isEnabled], [selected], and [clipBehavior] arguments must
|
||||
/// not be null. The [pressElevation] and [elevation] must be null or non-negative.
|
||||
/// Typically, [pressElevation] is greater than [elevation].
|
||||
/// The [label], [isEnabled], [selected], [autofocus], and [clipBehavior]
|
||||
/// arguments must not be null. The [pressElevation] and [elevation] must be
|
||||
/// null or non-negative. Typically, [pressElevation] is greater than
|
||||
/// [elevation].
|
||||
const RawChip({
|
||||
Key key,
|
||||
this.avatar,
|
||||
@@ -1311,6 +1364,8 @@ class RawChip extends StatefulWidget
|
||||
this.tooltip,
|
||||
this.shape,
|
||||
this.clipBehavior = Clip.none,
|
||||
this.focusNode,
|
||||
this.autofocus = false,
|
||||
this.backgroundColor,
|
||||
this.materialTapTargetSize,
|
||||
this.elevation,
|
||||
@@ -1321,6 +1376,7 @@ class RawChip extends StatefulWidget
|
||||
assert(isEnabled != null),
|
||||
assert(selected != null),
|
||||
assert(clipBehavior != null),
|
||||
assert(autofocus != null),
|
||||
assert(pressElevation == null || pressElevation >= 0.0),
|
||||
assert(elevation == null || elevation >= 0.0),
|
||||
deleteIcon = deleteIcon ?? _kDefaultDeleteIcon,
|
||||
@@ -1363,6 +1419,10 @@ class RawChip extends StatefulWidget
|
||||
@override
|
||||
final Clip clipBehavior;
|
||||
@override
|
||||
final FocusNode focusNode;
|
||||
@override
|
||||
final bool autofocus;
|
||||
@override
|
||||
final Color backgroundColor;
|
||||
@override
|
||||
final EdgeInsetsGeometry padding;
|
||||
@@ -1663,6 +1723,8 @@ class _RawChipState extends State<RawChip> with TickerProviderStateMixin<RawChip
|
||||
|
||||
Widget result = Focus(
|
||||
onFocusChange: _handleFocus,
|
||||
focusNode: widget.focusNode,
|
||||
autofocus: widget.autofocus,
|
||||
child: Material(
|
||||
elevation: isTapping ? pressElevation : elevation,
|
||||
shadowColor: widget.selected ? selectedShadowColor : shadowColor,
|
||||
|
||||
@@ -97,6 +97,8 @@ import 'theme_data.dart';
|
||||
/// * <https://material.io/design/components/buttons.html>
|
||||
class FlatButton extends MaterialButton {
|
||||
/// Create a simple text button.
|
||||
///
|
||||
/// The [autofocus] and [clipBehavior] arguments must not be null.
|
||||
const FlatButton({
|
||||
Key key,
|
||||
@required VoidCallback onPressed,
|
||||
@@ -115,9 +117,11 @@ class FlatButton extends MaterialButton {
|
||||
ShapeBorder shape,
|
||||
Clip clipBehavior,
|
||||
FocusNode focusNode,
|
||||
bool autofocus = false,
|
||||
MaterialTapTargetSize materialTapTargetSize,
|
||||
@required Widget child,
|
||||
}) : super(
|
||||
}) : assert(autofocus != null),
|
||||
super(
|
||||
key: key,
|
||||
onPressed: onPressed,
|
||||
onHighlightChanged: onHighlightChanged,
|
||||
@@ -135,6 +139,7 @@ class FlatButton extends MaterialButton {
|
||||
shape: shape,
|
||||
clipBehavior: clipBehavior,
|
||||
focusNode: focusNode,
|
||||
autofocus: autofocus,
|
||||
materialTapTargetSize: materialTapTargetSize,
|
||||
child: child,
|
||||
);
|
||||
@@ -164,6 +169,7 @@ class FlatButton extends MaterialButton {
|
||||
ShapeBorder shape,
|
||||
Clip clipBehavior,
|
||||
FocusNode focusNode,
|
||||
bool autofocus,
|
||||
MaterialTapTargetSize materialTapTargetSize,
|
||||
@required Widget icon,
|
||||
@required Widget label,
|
||||
@@ -192,6 +198,7 @@ class FlatButton extends MaterialButton {
|
||||
shape: buttonTheme.getShape(this),
|
||||
clipBehavior: clipBehavior ?? Clip.none,
|
||||
focusNode: focusNode,
|
||||
autofocus: autofocus,
|
||||
materialTapTargetSize: buttonTheme.getMaterialTapTargetSize(this),
|
||||
animationDuration: buttonTheme.getAnimationDuration(this),
|
||||
child: child,
|
||||
@@ -222,11 +229,13 @@ class _FlatButtonWithIcon extends FlatButton with MaterialButtonWithIconMixin {
|
||||
ShapeBorder shape,
|
||||
Clip clipBehavior,
|
||||
FocusNode focusNode,
|
||||
bool autofocus = false,
|
||||
MaterialTapTargetSize materialTapTargetSize,
|
||||
@required Widget icon,
|
||||
@required Widget label,
|
||||
}) : assert(icon != null),
|
||||
assert(label != null),
|
||||
assert(autofocus != null),
|
||||
super(
|
||||
key: key,
|
||||
onPressed: onPressed,
|
||||
@@ -245,6 +254,7 @@ class _FlatButtonWithIcon extends FlatButton with MaterialButtonWithIconMixin {
|
||||
shape: shape,
|
||||
clipBehavior: clipBehavior,
|
||||
focusNode: focusNode,
|
||||
autofocus: autofocus,
|
||||
materialTapTargetSize: materialTapTargetSize,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
|
||||
@@ -145,6 +145,7 @@ class FloatingActionButton extends StatelessWidget {
|
||||
this.shape,
|
||||
this.clipBehavior = Clip.none,
|
||||
this.focusNode,
|
||||
this.autofocus = false,
|
||||
this.materialTapTargetSize,
|
||||
this.isExtended = false,
|
||||
}) : assert(elevation == null || elevation >= 0.0),
|
||||
@@ -154,15 +155,16 @@ class FloatingActionButton extends StatelessWidget {
|
||||
assert(disabledElevation == null || disabledElevation >= 0.0),
|
||||
assert(mini != null),
|
||||
assert(isExtended != null),
|
||||
assert(autofocus != null),
|
||||
_sizeConstraints = mini ? _kMiniSizeConstraints : _kSizeConstraints,
|
||||
super(key: key);
|
||||
|
||||
/// Creates a wider [StadiumBorder]-shaped floating action button with
|
||||
/// an optional [icon] and a [label].
|
||||
///
|
||||
/// The [label] and [clipBehavior] arguments must non-null. Additionally,
|
||||
/// [elevation], [highlightElevation], and [disabledElevation] (if specified)
|
||||
/// must be non-negative.
|
||||
/// The [label], [autofocus], and [clipBehavior] arguments must non-null.
|
||||
/// Additionally, [elevation], [highlightElevation], and [disabledElevation]
|
||||
/// (if specified) must be non-negative.
|
||||
FloatingActionButton.extended({
|
||||
Key key,
|
||||
this.tooltip,
|
||||
@@ -183,6 +185,7 @@ class FloatingActionButton extends StatelessWidget {
|
||||
this.materialTapTargetSize,
|
||||
this.clipBehavior = Clip.none,
|
||||
this.focusNode,
|
||||
this.autofocus = false,
|
||||
Widget icon,
|
||||
@required Widget label,
|
||||
}) : assert(elevation == null || elevation >= 0.0),
|
||||
@@ -191,6 +194,7 @@ class FloatingActionButton extends StatelessWidget {
|
||||
assert(highlightElevation == null || highlightElevation >= 0.0),
|
||||
assert(disabledElevation == null || disabledElevation >= 0.0),
|
||||
assert(isExtended != null),
|
||||
assert(autofocus != null),
|
||||
_sizeConstraints = _kExtendedSizeConstraints,
|
||||
mini = false,
|
||||
child = _ChildOverflowBox(
|
||||
@@ -372,14 +376,12 @@ class FloatingActionButton extends StatelessWidget {
|
||||
/// floating action buttons are scaled and faded in.
|
||||
final bool isExtended;
|
||||
|
||||
/// An optional focus node to use for requesting focus when pressed.
|
||||
///
|
||||
/// If not supplied, the button will create and host its own [FocusNode].
|
||||
///
|
||||
/// If supplied, the given focusNode will be _hosted_ by this widget. See
|
||||
/// [FocusNode] for more information on what that implies.
|
||||
/// {@macro flutter.widgets.Focus.focusNode}
|
||||
final FocusNode focusNode;
|
||||
|
||||
/// {@macro flutter.widgets.Focus.autofocus}
|
||||
final bool autofocus;
|
||||
|
||||
/// Configures the minimum size of the tap target.
|
||||
///
|
||||
/// Defaults to [ThemeData.materialTapTargetSize].
|
||||
@@ -463,6 +465,7 @@ class FloatingActionButton extends StatelessWidget {
|
||||
shape: shape,
|
||||
clipBehavior: clipBehavior ?? Clip.none,
|
||||
focusNode: focusNode,
|
||||
autofocus: autofocus,
|
||||
child: child,
|
||||
);
|
||||
|
||||
|
||||
@@ -131,8 +131,8 @@ class IconButton extends StatelessWidget {
|
||||
///
|
||||
/// Requires one of its ancestors to be a [Material] widget.
|
||||
///
|
||||
/// The [iconSize], [padding], and [alignment] arguments must not be null (though
|
||||
/// they each have default values).
|
||||
/// The [iconSize], [padding], [autofocus], and [alignment] arguments must not
|
||||
/// be null (though they each have default values).
|
||||
///
|
||||
/// The [icon] argument must be specified, and is typically either an [Icon]
|
||||
/// or an [ImageIcon].
|
||||
@@ -150,10 +150,12 @@ class IconButton extends StatelessWidget {
|
||||
this.disabledColor,
|
||||
@required this.onPressed,
|
||||
this.focusNode,
|
||||
this.autofocus = false,
|
||||
this.tooltip,
|
||||
}) : assert(iconSize != null),
|
||||
assert(padding != null),
|
||||
assert(alignment != null),
|
||||
assert(autofocus != null),
|
||||
assert(icon != null),
|
||||
super(key: key);
|
||||
|
||||
@@ -256,14 +258,12 @@ class IconButton extends StatelessWidget {
|
||||
/// If this is set to null, the button will be disabled.
|
||||
final VoidCallback onPressed;
|
||||
|
||||
/// An optional focus node to use for requesting focus when pressed.
|
||||
///
|
||||
/// If not supplied, the button will create and host its own [FocusNode].
|
||||
///
|
||||
/// If supplied, the given focusNode will be _hosted_ by this widget. See
|
||||
/// [FocusNode] for more information on what that implies.
|
||||
/// {@macro flutter.widgets.Focus.focusNode}
|
||||
final FocusNode focusNode;
|
||||
|
||||
/// {@macro flutter.widgets.Focus.autofocus}
|
||||
final bool autofocus;
|
||||
|
||||
/// Text that describes the action that will occur when the button is pressed.
|
||||
///
|
||||
/// This text is displayed when the user long-presses on the button and is
|
||||
@@ -312,6 +312,7 @@ class IconButton extends StatelessWidget {
|
||||
enabled: onPressed != null,
|
||||
child: Focus(
|
||||
focusNode: focusNode,
|
||||
autofocus: autofocus,
|
||||
child: InkResponse(
|
||||
onTap: onPressed,
|
||||
child: result,
|
||||
|
||||
@@ -43,6 +43,11 @@ class MaterialButton extends StatelessWidget {
|
||||
/// Rather than creating a material button directly, consider using
|
||||
/// [FlatButton] or [RaisedButton]. To create a custom Material button
|
||||
/// consider using [RawMaterialButton].
|
||||
///
|
||||
/// The [autofocus] and [clipBehavior] arguments must not be null.
|
||||
/// Additionally, [elevation], [hoverElevation], [focusElevation],
|
||||
/// [highlightElevation], and [disabledElevation] must be non-negative, if
|
||||
/// specified.
|
||||
const MaterialButton({
|
||||
Key key,
|
||||
@required this.onPressed,
|
||||
@@ -66,12 +71,19 @@ class MaterialButton extends StatelessWidget {
|
||||
this.shape,
|
||||
this.clipBehavior = Clip.none,
|
||||
this.focusNode,
|
||||
this.autofocus = false,
|
||||
this.materialTapTargetSize,
|
||||
this.animationDuration,
|
||||
this.minWidth,
|
||||
this.height,
|
||||
this.child,
|
||||
}) : super(key: key);
|
||||
}) : assert(autofocus != null),
|
||||
assert(elevation == null || elevation >= 0.0),
|
||||
assert(focusElevation == null || focusElevation >= 0.0),
|
||||
assert(hoverElevation == null || hoverElevation >= 0.0),
|
||||
assert(highlightElevation == null || highlightElevation >= 0.0),
|
||||
assert(disabledElevation == null || disabledElevation >= 0.0),
|
||||
super(key: key);
|
||||
|
||||
/// The callback that is called when the button is tapped or otherwise activated.
|
||||
///
|
||||
@@ -296,14 +308,12 @@ class MaterialButton extends StatelessWidget {
|
||||
/// {@macro flutter.widgets.Clip}
|
||||
final Clip clipBehavior;
|
||||
|
||||
/// An optional focus node to use for requesting focus when pressed.
|
||||
///
|
||||
/// If not supplied, the button will create and host its own [FocusNode].
|
||||
///
|
||||
/// If supplied, the given focusNode will be _hosted_ by this widget. See
|
||||
/// [FocusNode] for more information on what that implies.
|
||||
/// {@macro flutter.widgets.Focus.focusNode}
|
||||
final FocusNode focusNode;
|
||||
|
||||
/// {@macro flutter.widgets.Focus.autofocus}
|
||||
final bool autofocus;
|
||||
|
||||
/// Defines the duration of animated changes for [shape] and [elevation].
|
||||
///
|
||||
/// The default value is [kThemeChangeDuration].
|
||||
|
||||
@@ -57,7 +57,7 @@ class OutlineButton extends MaterialButton {
|
||||
/// Create an outline button.
|
||||
///
|
||||
/// The [highlightElevation] argument must be null or a positive value
|
||||
/// and the [clipBehavior] argument must not be null.
|
||||
/// and the [autofocus] and [clipBehavior] arguments must not be null.
|
||||
const OutlineButton({
|
||||
Key key,
|
||||
@required VoidCallback onPressed,
|
||||
@@ -77,8 +77,10 @@ class OutlineButton extends MaterialButton {
|
||||
ShapeBorder shape,
|
||||
Clip clipBehavior,
|
||||
FocusNode focusNode,
|
||||
bool autofocus = false,
|
||||
Widget child,
|
||||
}) : assert(highlightElevation == null || highlightElevation >= 0.0),
|
||||
assert(autofocus != null),
|
||||
super(
|
||||
key: key,
|
||||
onPressed: onPressed,
|
||||
@@ -95,6 +97,7 @@ class OutlineButton extends MaterialButton {
|
||||
shape: shape,
|
||||
clipBehavior: clipBehavior,
|
||||
focusNode: focusNode,
|
||||
autofocus: autofocus,
|
||||
child: child,
|
||||
);
|
||||
|
||||
@@ -105,7 +108,7 @@ class OutlineButton extends MaterialButton {
|
||||
/// at the start, and 16 at the end, with an 8 pixel gap in between.
|
||||
///
|
||||
/// The [highlightElevation] argument must be null or a positive value. The
|
||||
/// [icon], [label], and [clipBehavior] arguments must not be null.
|
||||
/// [icon], [label], [autofocus], and [clipBehavior] arguments must not be null.
|
||||
factory OutlineButton.icon({
|
||||
Key key,
|
||||
@required VoidCallback onPressed,
|
||||
@@ -125,6 +128,7 @@ class OutlineButton extends MaterialButton {
|
||||
ShapeBorder shape,
|
||||
Clip clipBehavior,
|
||||
FocusNode focusNode,
|
||||
bool autofocus,
|
||||
@required Widget icon,
|
||||
@required Widget label,
|
||||
}) = _OutlineButtonWithIcon;
|
||||
@@ -218,9 +222,11 @@ class _OutlineButtonWithIcon extends OutlineButton with MaterialButtonWithIconMi
|
||||
ShapeBorder shape,
|
||||
Clip clipBehavior,
|
||||
FocusNode focusNode,
|
||||
bool autofocus = false,
|
||||
@required Widget icon,
|
||||
@required Widget label,
|
||||
}) : assert(highlightElevation == null || highlightElevation >= 0.0),
|
||||
assert(autofocus != null),
|
||||
assert(icon != null),
|
||||
assert(label != null),
|
||||
super(
|
||||
@@ -242,6 +248,7 @@ class _OutlineButtonWithIcon extends OutlineButton with MaterialButtonWithIconMi
|
||||
shape: shape,
|
||||
clipBehavior: clipBehavior,
|
||||
focusNode: focusNode,
|
||||
autofocus: autofocus,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
@@ -274,9 +281,11 @@ class _OutlineButton extends StatefulWidget {
|
||||
this.shape,
|
||||
this.clipBehavior,
|
||||
this.focusNode,
|
||||
this.autofocus = false,
|
||||
this.child,
|
||||
}) : assert(highlightElevation != null && highlightElevation >= 0.0),
|
||||
assert(highlightedBorderColor != null),
|
||||
assert(autofocus != null),
|
||||
super(key: key);
|
||||
|
||||
final VoidCallback onPressed;
|
||||
@@ -297,6 +306,7 @@ class _OutlineButton extends StatefulWidget {
|
||||
final ShapeBorder shape;
|
||||
final Clip clipBehavior;
|
||||
final FocusNode focusNode;
|
||||
final bool autofocus;
|
||||
final Widget child;
|
||||
|
||||
bool get enabled => onPressed != null;
|
||||
|
||||
@@ -101,9 +101,10 @@ import 'theme_data.dart';
|
||||
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.
|
||||
/// The [autofocus] and [clipBehavior] arguments must not be null.
|
||||
/// Additionally, [elevation], [hoverElevation], [focusElevation],
|
||||
/// [highlightElevation], and [disabledElevation] must be non-negative, if
|
||||
/// specified.
|
||||
const RaisedButton({
|
||||
Key key,
|
||||
@required VoidCallback onPressed,
|
||||
@@ -127,10 +128,12 @@ class RaisedButton extends MaterialButton {
|
||||
ShapeBorder shape,
|
||||
Clip clipBehavior,
|
||||
FocusNode focusNode,
|
||||
bool autofocus = false,
|
||||
MaterialTapTargetSize materialTapTargetSize,
|
||||
Duration animationDuration,
|
||||
Widget child,
|
||||
}) : assert(elevation == null || elevation >= 0.0),
|
||||
}) : assert(autofocus != null),
|
||||
assert(elevation == null || elevation >= 0.0),
|
||||
assert(focusElevation == null || focusElevation >= 0.0),
|
||||
assert(hoverElevation == null || hoverElevation >= 0.0),
|
||||
assert(highlightElevation == null || highlightElevation >= 0.0),
|
||||
@@ -158,6 +161,7 @@ class RaisedButton extends MaterialButton {
|
||||
shape: shape,
|
||||
clipBehavior: clipBehavior,
|
||||
focusNode: focusNode,
|
||||
autofocus: autofocus,
|
||||
materialTapTargetSize: materialTapTargetSize,
|
||||
animationDuration: animationDuration,
|
||||
child: child,
|
||||
@@ -191,6 +195,7 @@ class RaisedButton extends MaterialButton {
|
||||
ShapeBorder shape,
|
||||
Clip clipBehavior,
|
||||
FocusNode focusNode,
|
||||
bool autofocus,
|
||||
MaterialTapTargetSize materialTapTargetSize,
|
||||
Duration animationDuration,
|
||||
@required Widget icon,
|
||||
@@ -220,6 +225,7 @@ class RaisedButton extends MaterialButton {
|
||||
constraints: buttonTheme.getConstraints(this),
|
||||
shape: buttonTheme.getShape(this),
|
||||
focusNode: focusNode,
|
||||
autofocus: autofocus,
|
||||
animationDuration: buttonTheme.getAnimationDuration(this),
|
||||
materialTapTargetSize: buttonTheme.getMaterialTapTargetSize(this),
|
||||
child: child,
|
||||
@@ -262,6 +268,7 @@ class _RaisedButtonWithIcon extends RaisedButton with MaterialButtonWithIconMixi
|
||||
ShapeBorder shape,
|
||||
Clip clipBehavior = Clip.none,
|
||||
FocusNode focusNode,
|
||||
bool autofocus = false,
|
||||
MaterialTapTargetSize materialTapTargetSize,
|
||||
Duration animationDuration,
|
||||
@required Widget icon,
|
||||
@@ -271,6 +278,7 @@ class _RaisedButtonWithIcon extends RaisedButton with MaterialButtonWithIconMixi
|
||||
assert(disabledElevation == null || disabledElevation >= 0.0),
|
||||
assert(icon != null),
|
||||
assert(label != null),
|
||||
assert(autofocus != null),
|
||||
super(
|
||||
key: key,
|
||||
onPressed: onPressed,
|
||||
@@ -291,6 +299,7 @@ class _RaisedButtonWithIcon extends RaisedButton with MaterialButtonWithIconMixi
|
||||
shape: shape,
|
||||
clipBehavior: clipBehavior,
|
||||
focusNode: focusNode,
|
||||
autofocus: autofocus,
|
||||
materialTapTargetSize: materialTapTargetSize,
|
||||
animationDuration: animationDuration,
|
||||
child: Row(
|
||||
|
||||
@@ -184,7 +184,10 @@ class SelectableText extends StatefulWidget {
|
||||
/// If the [style] argument is null, the text will use the style from the
|
||||
/// closest enclosing [DefaultTextStyle].
|
||||
///
|
||||
/// The [data] parameter must not be null.
|
||||
|
||||
/// The [showCursor], [autofocus], [dragStartBehavior], and [data] parameters
|
||||
/// must not be null. If specified, the [maxLines] argument must be greater
|
||||
/// than zero.
|
||||
const SelectableText(
|
||||
this.data, {
|
||||
Key key,
|
||||
@@ -225,6 +228,8 @@ class SelectableText extends StatefulWidget {
|
||||
///
|
||||
/// The [textSpan] parameter must not be null and only contain [TextSpan] in
|
||||
/// [textSpan.children]. Other type of [InlineSpan] is not allowed.
|
||||
///
|
||||
/// The [autofocus] and [dragStartBehavior] arguments must not be null.
|
||||
const SelectableText.rich(
|
||||
this.textSpan, {
|
||||
Key key,
|
||||
|
||||
@@ -679,13 +679,7 @@ class _ToggleButton extends StatelessWidget {
|
||||
/// The splash color for the button's [InkWell].
|
||||
final Color splashColor;
|
||||
|
||||
/// A leaf node in the focus tree for this button.
|
||||
///
|
||||
/// Focus is used to determine which widget should be affected by keyboard
|
||||
/// events. The focus tree keeps track of which widget is currently focused
|
||||
/// on by the user.
|
||||
///
|
||||
/// See [FocusNode] for more information about how focus nodes are used.
|
||||
/// {@macro flutter.widgets.Focus.focusNode}
|
||||
final FocusNode focusNode;
|
||||
|
||||
/// Called when the button is tapped or otherwise activated.
|
||||
|
||||
@@ -339,9 +339,12 @@ class EditableText extends StatefulWidget {
|
||||
/// The text cursor is not shown if [showCursor] is false or if [showCursor]
|
||||
/// is null (the default) and [readOnly] is true.
|
||||
///
|
||||
/// The [controller], [focusNode], [style], [cursorColor], [backgroundCursorColor],
|
||||
/// [textAlign], [dragStartBehavior], [rendererIgnoresPointer] and [readOnly]
|
||||
/// arguments must not be null.
|
||||
/// The [controller], [focusNode], [obscureText], [autocorrect], [autofocus],
|
||||
/// [showSelectionHandles], [enableInteractiveSelection], [forceLine],
|
||||
/// [style], [cursorColor], [cursorOpacityAnimates],[backgroundCursorColor],
|
||||
/// [paintCursorAboveText], [textAlign], [dragStartBehavior], [scrollPadding],
|
||||
/// [dragStartBehavior], [toolbarOptions], [rendererIgnoresPointer], and
|
||||
/// [readOnly] arguments must not be null.
|
||||
EditableText({
|
||||
Key key,
|
||||
@required this.controller,
|
||||
|
||||
@@ -137,7 +137,7 @@ class Focus extends StatefulWidget {
|
||||
///
|
||||
/// The [child] argument is required and must not be null.
|
||||
///
|
||||
/// The [autofocus] argument must not be null.
|
||||
/// The [autofocus] and [skipTraversal] arguments must not be null.
|
||||
const Focus({
|
||||
Key key,
|
||||
@required this.child,
|
||||
@@ -190,24 +190,33 @@ class Focus extends StatefulWidget {
|
||||
/// focus.
|
||||
final ValueChanged<bool> onFocusChange;
|
||||
|
||||
/// {@template flutter.widgets.Focus.autofocus}
|
||||
/// True if this widget will be selected as the initial focus when no other
|
||||
/// node in its scope is currently focused.
|
||||
///
|
||||
/// Ideally, there is only one [Focus] with autofocus set in each
|
||||
/// [FocusScope]. If there is more than one [Focus] with autofocus set, then
|
||||
/// the first one added to the tree will get focus.
|
||||
/// Ideally, there is only one widget with autofocus set in each [FocusScope].
|
||||
/// If there is more than one widget with autofocus set, then the first one
|
||||
/// added to the tree will get focus.
|
||||
///
|
||||
/// Must not be null. Defaults to false.
|
||||
/// {@endtemplate}
|
||||
final bool autofocus;
|
||||
|
||||
/// An optional focus node to use as the focus node for this [Focus] widget.
|
||||
/// {@template flutter.widgets.Focus.focusNode}
|
||||
/// An optional focus node to use as the focus node for this widget.
|
||||
///
|
||||
/// If one is not supplied, then one will be allocated and owned by this
|
||||
/// widget.
|
||||
/// If one is not supplied, then one will be automatically allocated, owned,
|
||||
/// and managed by this widget. The widget will be focusable even if a
|
||||
/// [focusNode] is not supplied. If supplied, the given `focusNode` will be
|
||||
/// _hosted_ by this widget, but not owned. See [FocusNode] for more
|
||||
/// information on what being hosted and/or owned implies.
|
||||
///
|
||||
/// Supplying a focus node is sometimes useful if an ancestor to this widget
|
||||
/// wants to control when this widget has the focus. The owner will be
|
||||
/// responsible for calling [FocusNode.dispose] on the focus node when it is
|
||||
/// done with it, but this [Focus] widget will attach/detach and reparent the
|
||||
/// node when needed.
|
||||
/// done with it, but this widget will attach/detach and reparent the node
|
||||
/// when needed.
|
||||
/// {@endtemplate}
|
||||
final FocusNode focusNode;
|
||||
|
||||
/// Sets the [FocusNode.skipTraversal] flag on the focus node so that it won't
|
||||
|
||||
@@ -31,18 +31,27 @@ class RawKeyboardListener extends StatefulWidget {
|
||||
///
|
||||
/// For text entry, consider using a [EditableText], which integrates with
|
||||
/// on-screen keyboards and input method editors (IMEs).
|
||||
///
|
||||
/// The [focusNode] and [child] arguments are required and must not be null.
|
||||
///
|
||||
/// The [autofocus] argument must not be null.
|
||||
const RawKeyboardListener({
|
||||
Key key,
|
||||
@required this.focusNode,
|
||||
@required this.onKey,
|
||||
this.autofocus = false,
|
||||
this.onKey,
|
||||
@required this.child,
|
||||
}) : assert(focusNode != null),
|
||||
assert(autofocus != null),
|
||||
assert(child != null),
|
||||
super(key: key);
|
||||
|
||||
/// Controls whether this widget has keyboard focus.
|
||||
/// {@macro flutter.widgets.Focus.focusNode}
|
||||
final FocusNode focusNode;
|
||||
|
||||
/// {@macro flutter.widgets.Focus.autofocus}
|
||||
final bool autofocus;
|
||||
|
||||
/// Called whenever this widget receives a raw keyboard event.
|
||||
final ValueChanged<RawKeyEvent> onKey;
|
||||
|
||||
@@ -113,5 +122,11 @@ class _RawKeyboardListenerState extends State<RawKeyboardListener> {
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Focus(focusNode: widget.focusNode, child: widget.child);
|
||||
Widget build(BuildContext context) {
|
||||
return Focus(
|
||||
focusNode: widget.focusNode,
|
||||
autofocus: widget.autofocus,
|
||||
child: widget.child,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user