Revert ActivateAction PR (#41945)
diff --git a/dev/manual_tests/lib/actions.dart b/dev/manual_tests/lib/actions.dart
index b76fad1..a09d754 100644
--- a/dev/manual_tests/lib/actions.dart
+++ b/dev/manual_tests/lib/actions.dart
@@ -247,8 +247,8 @@
}
}
-class UndoableFocusActionBase extends UndoableAction {
- UndoableFocusActionBase(LocalKey name) : super(name);
+class SetFocusActionBase extends UndoableAction {
+ SetFocusActionBase(LocalKey name) : super(name);
FocusNode _previousFocus;
@@ -286,8 +286,10 @@
}
}
-class UndoableRequestFocusAction extends UndoableFocusActionBase {
- UndoableRequestFocusAction() : super(RequestFocusAction.key);
+class SetFocusAction extends SetFocusActionBase {
+ SetFocusAction() : super(key);
+
+ static const LocalKey key = ValueKey<Type>(SetFocusAction);
@override
void invoke(FocusNode node, Intent intent) {
@@ -297,8 +299,10 @@
}
/// Actions for manipulating focus.
-class UndoableNextFocusAction extends UndoableFocusActionBase {
- UndoableNextFocusAction() : super(NextFocusAction.key);
+class NextFocusAction extends SetFocusActionBase {
+ NextFocusAction() : super(key);
+
+ static const LocalKey key = ValueKey<Type>(NextFocusAction);
@override
void invoke(FocusNode node, Intent intent) {
@@ -307,8 +311,10 @@
}
}
-class UndoablePreviousFocusAction extends UndoableFocusActionBase {
- UndoablePreviousFocusAction() : super(PreviousFocusAction.key);
+class PreviousFocusAction extends SetFocusActionBase {
+ PreviousFocusAction() : super(key);
+
+ static const LocalKey key = ValueKey<Type>(PreviousFocusAction);
@override
void invoke(FocusNode node, Intent intent) {
@@ -317,8 +323,16 @@
}
}
-class UndoableDirectionalFocusAction extends UndoableFocusActionBase {
- UndoableDirectionalFocusAction() : super(DirectionalFocusAction.key);
+class DirectionalFocusIntent extends Intent {
+ const DirectionalFocusIntent(this.direction) : super(DirectionalFocusAction.key);
+
+ final TraversalDirection direction;
+}
+
+class DirectionalFocusAction extends SetFocusActionBase {
+ DirectionalFocusAction() : super(key);
+
+ static const LocalKey key = ValueKey<Type>(DirectionalFocusAction);
TraversalDirection direction;
@@ -352,7 +366,7 @@
void _handleOnPressed() {
print('Button ${widget.name} pressed.');
setState(() {
- Actions.invoke(context, const Intent(RequestFocusAction.key), focusNode: _focusNode);
+ Actions.invoke(context, const Intent(SetFocusAction.key), focusNode: _focusNode);
});
}
@@ -420,91 +434,101 @@
@override
Widget build(BuildContext context) {
final TextTheme textTheme = Theme.of(context).textTheme;
- return Actions(
- dispatcher: dispatcher,
- actions: <LocalKey, ActionFactory>{
- RequestFocusAction.key: () => UndoableRequestFocusAction(),
- NextFocusAction.key: () => UndoableNextFocusAction(),
- PreviousFocusAction.key: () => UndoablePreviousFocusAction(),
- DirectionalFocusAction.key: () => UndoableDirectionalFocusAction(),
- kUndoActionKey: () => kUndoAction,
- kRedoActionKey: () => kRedoAction,
+ return Shortcuts(
+ shortcuts: <LogicalKeySet, Intent>{
+ LogicalKeySet(LogicalKeyboardKey.tab): const Intent(NextFocusAction.key),
+ LogicalKeySet(LogicalKeyboardKey.shift, LogicalKeyboardKey.tab): const Intent(PreviousFocusAction.key),
+ LogicalKeySet(LogicalKeyboardKey.arrowUp): const DirectionalFocusIntent(TraversalDirection.up),
+ LogicalKeySet(LogicalKeyboardKey.arrowDown): const DirectionalFocusIntent(TraversalDirection.down),
+ LogicalKeySet(LogicalKeyboardKey.arrowLeft): const DirectionalFocusIntent(TraversalDirection.left),
+ LogicalKeySet(LogicalKeyboardKey.arrowRight): const DirectionalFocusIntent(TraversalDirection.right),
},
- child: DefaultFocusTraversal(
- policy: ReadingOrderTraversalPolicy(),
- child: Shortcuts(
- shortcuts: <LogicalKeySet, Intent>{
- LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.shift, LogicalKeyboardKey.keyZ): kRedoIntent,
- LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyZ): kUndoIntent,
- },
- child: FocusScope(
- debugLabel: 'Scope',
- autofocus: true,
- child: DefaultTextStyle(
- style: textTheme.display1,
- child: Scaffold(
- appBar: AppBar(
- title: const Text('Actions Demo'),
- ),
- body: Center(
- child: Builder(builder: (BuildContext context) {
- return Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: <Widget>[
- Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: const <Widget>[
- DemoButton(name: 'One'),
- DemoButton(name: 'Two'),
- DemoButton(name: 'Three'),
- ],
- ),
- Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: const <Widget>[
- DemoButton(name: 'Four'),
- DemoButton(name: 'Five'),
- DemoButton(name: 'Six'),
- ],
- ),
- Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: const <Widget>[
- DemoButton(name: 'Seven'),
- DemoButton(name: 'Eight'),
- DemoButton(name: 'Nine'),
- ],
- ),
- Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: <Widget>[
- Padding(
- padding: const EdgeInsets.all(8.0),
- child: RaisedButton(
- child: const Text('UNDO'),
- onPressed: canUndo
- ? () {
- Actions.invoke(context, kUndoIntent);
- }
- : null,
+ child: Actions(
+ dispatcher: dispatcher,
+ actions: <LocalKey, ActionFactory>{
+ SetFocusAction.key: () => SetFocusAction(),
+ NextFocusAction.key: () => NextFocusAction(),
+ PreviousFocusAction.key: () => PreviousFocusAction(),
+ DirectionalFocusAction.key: () => DirectionalFocusAction(),
+ kUndoActionKey: () => kUndoAction,
+ kRedoActionKey: () => kRedoAction,
+ },
+ child: DefaultFocusTraversal(
+ policy: ReadingOrderTraversalPolicy(),
+ child: Shortcuts(
+ shortcuts: <LogicalKeySet, Intent>{
+ LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.shift, LogicalKeyboardKey.keyZ): kRedoIntent,
+ LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyZ): kUndoIntent,
+ },
+ child: FocusScope(
+ debugLabel: 'Scope',
+ autofocus: true,
+ child: DefaultTextStyle(
+ style: textTheme.display1,
+ child: Scaffold(
+ appBar: AppBar(
+ title: const Text('Actions Demo'),
+ ),
+ body: Center(
+ child: Builder(builder: (BuildContext context) {
+ return Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: <Widget>[
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: const <Widget>[
+ DemoButton(name: 'One'),
+ DemoButton(name: 'Two'),
+ DemoButton(name: 'Three'),
+ ],
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: const <Widget>[
+ DemoButton(name: 'Four'),
+ DemoButton(name: 'Five'),
+ DemoButton(name: 'Six'),
+ ],
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: const <Widget>[
+ DemoButton(name: 'Seven'),
+ DemoButton(name: 'Eight'),
+ DemoButton(name: 'Nine'),
+ ],
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: <Widget>[
+ Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: RaisedButton(
+ child: const Text('UNDO'),
+ onPressed: canUndo
+ ? () {
+ Actions.invoke(context, kUndoIntent);
+ }
+ : null,
+ ),
),
- ),
- Padding(
- padding: const EdgeInsets.all(8.0),
- child: RaisedButton(
- child: const Text('REDO'),
- onPressed: canRedo
- ? () {
- Actions.invoke(context, kRedoIntent);
- }
- : null,
+ Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: RaisedButton(
+ child: const Text('REDO'),
+ onPressed: canRedo
+ ? () {
+ Actions.invoke(context, kRedoIntent);
+ }
+ : null,
+ ),
),
- ),
- ],
- ),
- ],
- );
- }),
+ ],
+ ),
+ ],
+ );
+ }),
+ ),
),
),
),
diff --git a/packages/flutter/lib/src/material/bottom_navigation_bar.dart b/packages/flutter/lib/src/material/bottom_navigation_bar.dart
index f32b268..2151cca 100644
--- a/packages/flutter/lib/src/material/bottom_navigation_bar.dart
+++ b/packages/flutter/lib/src/material/bottom_navigation_bar.dart
@@ -474,43 +474,45 @@
child: Semantics(
container: true,
selected: selected,
- child: Stack(
- children: <Widget>[
- InkResponse(
- onTap: onTap,
- child: Padding(
- padding: EdgeInsets.only(top: topPadding, bottom: bottomPadding),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.center,
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- mainAxisSize: MainAxisSize.min,
- children: <Widget>[
- _TileIcon(
- colorTween: colorTween,
- animation: animation,
- iconSize: iconSize,
- selected: selected,
- item: item,
- selectedIconTheme: selectedIconTheme,
- unselectedIconTheme: unselectedIconTheme,
- ),
- _Label(
- colorTween: colorTween,
- animation: animation,
- item: item,
- selectedLabelStyle: selectedLabelStyle,
- unselectedLabelStyle: unselectedLabelStyle,
- showSelectedLabels: showSelectedLabels,
- showUnselectedLabels: showUnselectedLabels,
- ),
- ],
+ child: Focus(
+ child: Stack(
+ children: <Widget>[
+ InkResponse(
+ onTap: onTap,
+ child: Padding(
+ padding: EdgeInsets.only(top: topPadding, bottom: bottomPadding),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ mainAxisSize: MainAxisSize.min,
+ children: <Widget>[
+ _TileIcon(
+ colorTween: colorTween,
+ animation: animation,
+ iconSize: iconSize,
+ selected: selected,
+ item: item,
+ selectedIconTheme: selectedIconTheme,
+ unselectedIconTheme: unselectedIconTheme,
+ ),
+ _Label(
+ colorTween: colorTween,
+ animation: animation,
+ item: item,
+ selectedLabelStyle: selectedLabelStyle,
+ unselectedLabelStyle: unselectedLabelStyle,
+ showSelectedLabels: showSelectedLabels,
+ showUnselectedLabels: showUnselectedLabels,
+ ),
+ ],
+ ),
),
),
- ),
- Semantics(
- label: indexLabel,
- ),
- ],
+ Semantics(
+ label: indexLabel,
+ ),
+ ],
+ ),
),
),
);
diff --git a/packages/flutter/lib/src/material/button.dart b/packages/flutter/lib/src/material/button.dart
index 367344b..3f438f1 100644
--- a/packages/flutter/lib/src/material/button.dart
+++ b/packages/flutter/lib/src/material/button.dart
@@ -330,37 +330,39 @@
final Color effectiveTextColor = MaterialStateProperty.resolveAs<Color>(widget.textStyle?.color, _states);
final ShapeBorder effectiveShape = MaterialStateProperty.resolveAs<ShapeBorder>(widget.shape, _states);
- final Widget result = ConstrainedBox(
- constraints: widget.constraints,
- child: Material(
- elevation: _effectiveElevation,
- textStyle: widget.textStyle?.copyWith(color: effectiveTextColor),
- shape: effectiveShape,
- color: widget.fillColor,
- type: widget.fillColor == null ? MaterialType.transparency : MaterialType.button,
- animationDuration: widget.animationDuration,
- clipBehavior: widget.clipBehavior,
- child: InkWell(
- focusNode: widget.focusNode,
- canRequestFocus: widget.enabled,
- onFocusChange: _handleFocusedChanged,
- autofocus: widget.autofocus,
- onHighlightChanged: _handleHighlightChanged,
- splashColor: widget.splashColor,
- highlightColor: widget.highlightColor,
- focusColor: widget.focusColor,
- hoverColor: widget.hoverColor,
- onHover: _handleHoveredChanged,
- onTap: widget.onPressed,
- customBorder: effectiveShape,
- child: IconTheme.merge(
- data: IconThemeData(color: effectiveTextColor),
- child: Container(
- padding: widget.padding,
- child: Center(
- widthFactor: 1.0,
- heightFactor: 1.0,
- child: widget.child,
+ final Widget result = Focus(
+ focusNode: widget.focusNode,
+ canRequestFocus: widget.enabled,
+ onFocusChange: _handleFocusedChanged,
+ autofocus: widget.autofocus,
+ child: ConstrainedBox(
+ constraints: widget.constraints,
+ child: Material(
+ elevation: _effectiveElevation,
+ textStyle: widget.textStyle?.copyWith(color: effectiveTextColor),
+ shape: effectiveShape,
+ color: widget.fillColor,
+ type: widget.fillColor == null ? MaterialType.transparency : MaterialType.button,
+ animationDuration: widget.animationDuration,
+ clipBehavior: widget.clipBehavior,
+ child: InkWell(
+ onHighlightChanged: _handleHighlightChanged,
+ splashColor: widget.splashColor,
+ highlightColor: widget.highlightColor,
+ focusColor: widget.focusColor,
+ hoverColor: widget.hoverColor,
+ onHover: _handleHoveredChanged,
+ onTap: widget.onPressed,
+ customBorder: effectiveShape,
+ child: IconTheme.merge(
+ data: IconThemeData(color: effectiveTextColor),
+ child: Container(
+ padding: widget.padding,
+ child: Center(
+ widthFactor: 1.0,
+ heightFactor: 1.0,
+ child: widget.child,
+ ),
),
),
),
diff --git a/packages/flutter/lib/src/material/chip.dart b/packages/flutter/lib/src/material/chip.dart
index 64d0869..669abac 100644
--- a/packages/flutter/lib/src/material/chip.dart
+++ b/packages/flutter/lib/src/material/chip.dart
@@ -1774,71 +1774,73 @@
final Color resolvedLabelColor = MaterialStateProperty.resolveAs<Color>(effectiveLabelStyle?.color, _states);
final TextStyle resolvedLabelStyle = effectiveLabelStyle?.copyWith(color: resolvedLabelColor);
- Widget result = Material(
- elevation: isTapping ? pressElevation : elevation,
- shadowColor: widget.selected ? selectedShadowColor : shadowColor,
- animationDuration: pressedAnimationDuration,
- shape: shape,
- clipBehavior: widget.clipBehavior,
- child: InkWell(
- onFocusChange: _handleFocus,
- focusNode: widget.focusNode,
- autofocus: widget.autofocus,
- canRequestFocus: widget.isEnabled,
- onTap: canTap ? _handleTap : null,
- onTapDown: canTap ? _handleTapDown : null,
- onTapCancel: canTap ? _handleTapCancel : null,
- onHover: canTap ? _handleHover : null,
- customBorder: shape,
- child: AnimatedBuilder(
- animation: Listenable.merge(<Listenable>[selectController, enableController]),
- builder: (BuildContext context, Widget child) {
- return Container(
- decoration: ShapeDecoration(
- shape: shape,
- color: getBackgroundColor(chipTheme),
+ Widget result = Focus(
+ onFocusChange: _handleFocus,
+ focusNode: widget.focusNode,
+ autofocus: widget.autofocus,
+ canRequestFocus: widget.isEnabled,
+ child: Material(
+ elevation: isTapping ? pressElevation : elevation,
+ shadowColor: widget.selected ? selectedShadowColor : shadowColor,
+ animationDuration: pressedAnimationDuration,
+ shape: shape,
+ clipBehavior: widget.clipBehavior,
+ child: InkWell(
+ onTap: canTap ? _handleTap : null,
+ onTapDown: canTap ? _handleTapDown : null,
+ onTapCancel: canTap ? _handleTapCancel : null,
+ onHover: canTap ? _handleHover : null,
+ customBorder: shape,
+ child: AnimatedBuilder(
+ animation: Listenable.merge(<Listenable>[selectController, enableController]),
+ builder: (BuildContext context, Widget child) {
+ return Container(
+ decoration: ShapeDecoration(
+ shape: shape,
+ color: getBackgroundColor(chipTheme),
+ ),
+ child: child,
+ );
+ },
+ child: _wrapWithTooltip(
+ widget.tooltip,
+ widget.onPressed,
+ _ChipRenderWidget(
+ theme: _ChipRenderTheme(
+ label: DefaultTextStyle(
+ overflow: TextOverflow.fade,
+ textAlign: TextAlign.start,
+ maxLines: 1,
+ softWrap: false,
+ style: resolvedLabelStyle,
+ child: widget.label,
+ ),
+ avatar: AnimatedSwitcher(
+ child: widget.avatar,
+ duration: _kDrawerDuration,
+ switchInCurve: Curves.fastOutSlowIn,
+ ),
+ deleteIcon: AnimatedSwitcher(
+ child: _buildDeleteIcon(context, theme, chipTheme),
+ duration: _kDrawerDuration,
+ switchInCurve: Curves.fastOutSlowIn,
+ ),
+ brightness: chipTheme.brightness,
+ padding: (widget.padding ?? chipTheme.padding).resolve(textDirection),
+ labelPadding: (widget.labelPadding ?? chipTheme.labelPadding).resolve(textDirection),
+ showAvatar: hasAvatar,
+ showCheckmark: showCheckmark,
+ checkmarkColor: checkmarkColor,
+ canTapBody: canTap,
+ ),
+ value: widget.selected,
+ checkmarkAnimation: checkmarkAnimation,
+ enableAnimation: enableAnimation,
+ avatarDrawerAnimation: avatarDrawerAnimation,
+ deleteDrawerAnimation: deleteDrawerAnimation,
+ isEnabled: widget.isEnabled,
+ avatarBorder: widget.avatarBorder,
),
- child: child,
- );
- },
- child: _wrapWithTooltip(
- widget.tooltip,
- widget.onPressed,
- _ChipRenderWidget(
- theme: _ChipRenderTheme(
- label: DefaultTextStyle(
- overflow: TextOverflow.fade,
- textAlign: TextAlign.start,
- maxLines: 1,
- softWrap: false,
- style: resolvedLabelStyle,
- child: widget.label,
- ),
- avatar: AnimatedSwitcher(
- child: widget.avatar,
- duration: _kDrawerDuration,
- switchInCurve: Curves.fastOutSlowIn,
- ),
- deleteIcon: AnimatedSwitcher(
- child: _buildDeleteIcon(context, theme, chipTheme),
- duration: _kDrawerDuration,
- switchInCurve: Curves.fastOutSlowIn,
- ),
- brightness: chipTheme.brightness,
- padding: (widget.padding ?? chipTheme.padding).resolve(textDirection),
- labelPadding: (widget.labelPadding ?? chipTheme.labelPadding).resolve(textDirection),
- showAvatar: hasAvatar,
- showCheckmark: showCheckmark,
- checkmarkColor: checkmarkColor,
- canTapBody: canTap,
- ),
- value: widget.selected,
- checkmarkAnimation: checkmarkAnimation,
- enableAnimation: enableAnimation,
- avatarDrawerAnimation: avatarDrawerAnimation,
- deleteDrawerAnimation: deleteDrawerAnimation,
- isEnabled: widget.isEnabled,
- avatarBorder: widget.avatarBorder,
),
),
),
diff --git a/packages/flutter/lib/src/material/icon_button.dart b/packages/flutter/lib/src/material/icon_button.dart
index 6fe788d..e2ef27d 100644
--- a/packages/flutter/lib/src/material/icon_button.dart
+++ b/packages/flutter/lib/src/material/icon_button.dart
@@ -309,20 +309,22 @@
return Semantics(
button: true,
enabled: onPressed != null,
- child: InkResponse(
+ child: Focus(
focusNode: focusNode,
autofocus: autofocus,
canRequestFocus: onPressed != null,
- onTap: onPressed,
- child: result,
- focusColor: focusColor ?? Theme.of(context).focusColor,
- hoverColor: hoverColor ?? Theme.of(context).hoverColor,
- highlightColor: highlightColor ?? Theme.of(context).highlightColor,
- splashColor: splashColor ?? Theme.of(context).splashColor,
- radius: math.max(
- Material.defaultSplashRadius,
- (iconSize + math.min(padding.horizontal, padding.vertical)) * 0.7,
- // x 0.5 for diameter -> radius and + 40% overflow derived from other Material apps.
+ child: InkResponse(
+ onTap: onPressed,
+ child: result,
+ focusColor: focusColor ?? Theme.of(context).focusColor,
+ hoverColor: hoverColor ?? Theme.of(context).hoverColor,
+ highlightColor: highlightColor ?? Theme.of(context).highlightColor,
+ splashColor: splashColor ?? Theme.of(context).splashColor,
+ radius: math.max(
+ Material.defaultSplashRadius,
+ (iconSize + math.min(padding.horizontal, padding.vertical)) * 0.7,
+ // x 0.5 for diameter -> radius and + 40% overflow derived from other Material apps.
+ ),
),
),
);
diff --git a/packages/flutter/lib/src/material/ink_well.dart b/packages/flutter/lib/src/material/ink_well.dart
index 01628a6..a69c8ff 100644
--- a/packages/flutter/lib/src/material/ink_well.dart
+++ b/packages/flutter/lib/src/material/ink_well.dart
@@ -210,16 +210,10 @@
this.splashFactory,
this.enableFeedback = true,
this.excludeFromSemantics = false,
- this.focusNode,
- this.canRequestFocus = true,
- this.onFocusChange,
- this.autofocus = false,
}) : assert(containedInkWell != null),
assert(highlightShape != null),
assert(enableFeedback != null),
assert(excludeFromSemantics != null),
- assert(autofocus != null),
- assert(canRequestFocus != null),
super(key: key);
/// The widget below this widget in the tree.
@@ -406,21 +400,6 @@
/// duplication of information.
final bool excludeFromSemantics;
- /// Handler called when the focus changes.
- ///
- /// Called with true if this widget's node gains focus, and false if it loses
- /// focus.
- final ValueChanged<bool> onFocusChange;
-
- /// {@macro flutter.widgets.Focus.autofocus}
- final bool autofocus;
-
- /// {@macro flutter.widgets.Focus.focusNode}
- final FocusNode focusNode;
-
- /// {@template flutter.widgets.Focus.canRequestFocus}
- final bool canRequestFocus;
-
/// The rectangle to use for the highlight effect and for clipping
/// the splash effects if [containedInkWell] is true.
///
@@ -483,6 +462,7 @@
class _InkResponseState<T extends InkResponse> extends State<T> with AutomaticKeepAliveClientMixin<T> {
Set<InteractiveInkFeature> _splashes;
InteractiveInkFeature _currentSplash;
+ FocusNode _focusNode;
bool _hovering = false;
final Map<_HighlightType, InkHighlight> _highlights = <_HighlightType, InkHighlight>{};
@@ -495,17 +475,26 @@
}
@override
+ void didChangeDependencies() {
+ super.didChangeDependencies();
+ _focusNode?.removeListener(_handleFocusUpdate);
+ _focusNode = Focus.of(context, nullOk: true);
+ _focusNode?.addListener(_handleFocusUpdate);
+ }
+
+ @override
void didUpdateWidget(InkResponse oldWidget) {
super.didUpdateWidget(oldWidget);
if (_isWidgetEnabled(widget) != _isWidgetEnabled(oldWidget)) {
_handleHoverChange(_hovering);
- _updateFocusHighlights();
+ _handleFocusUpdate();
}
}
@override
void dispose() {
WidgetsBinding.instance.focusManager.removeHighlightModeListener(_handleFocusHighlightModeChange);
+ _focusNode?.removeListener(_handleFocusUpdate);
super.dispose();
}
@@ -571,7 +560,7 @@
}
assert(value == (_highlights[type] != null && _highlights[type].active));
- switch (type) {
+ switch(type) {
case _HighlightType.pressed:
if (widget.onHighlightChanged != null)
widget.onHighlightChanged(value);
@@ -585,10 +574,10 @@
}
}
- InteractiveInkFeature _createInkFeature(Offset globalPosition) {
+ InteractiveInkFeature _createInkFeature(TapDownDetails details) {
final MaterialInkController inkController = Material.of(context);
final RenderBox referenceBox = context.findRenderObject();
- final Offset position = referenceBox.globalToLocal(globalPosition);
+ final Offset position = referenceBox.globalToLocal(details.globalPosition);
final Color color = widget.splashColor ?? Theme.of(context).splashColor;
final RectCallback rectCallback = widget.containedInkWell ? widget.getRectCallback(referenceBox) : null;
final BorderRadius borderRadius = widget.borderRadius;
@@ -627,54 +616,31 @@
return;
}
setState(() {
- _updateFocusHighlights();
+ _handleFocusUpdate();
});
}
- void _updateFocusHighlights() {
+ void _handleFocusUpdate() {
bool showFocus;
switch (WidgetsBinding.instance.focusManager.highlightMode) {
case FocusHighlightMode.touch:
showFocus = false;
break;
case FocusHighlightMode.traditional:
- showFocus = enabled && _hasFocus;
+ showFocus = enabled && (Focus.of(context, nullOk: true)?.hasPrimaryFocus ?? false);
break;
}
updateHighlight(_HighlightType.focus, value: showFocus);
}
- bool _hasFocus = false;
- void _handleFocusUpdate(bool hasFocus) {
- _hasFocus = hasFocus;
- _updateFocusHighlights();
- if (widget.onFocusChange != null) {
- widget.onFocusChange(hasFocus);
- }
- }
-
void _handleTapDown(TapDownDetails details) {
- _startSplash(details: details);
- if (widget.onTapDown != null) {
- widget.onTapDown(details);
- }
- }
-
- void _startSplash({TapDownDetails details, BuildContext context}) {
- assert(details != null || context != null);
-
- Offset globalPosition;
- if (context != null) {
- final RenderBox referenceBox = context.findRenderObject();
- assert(referenceBox.hasSize, 'InkResponse must be done with layout before starting a splash.');
- globalPosition = referenceBox.localToGlobal(referenceBox.paintBounds.center);
- } else {
- globalPosition = details.globalPosition;
- }
- final InteractiveInkFeature splash = _createInkFeature(globalPosition);
+ final InteractiveInkFeature splash = _createInkFeature(details);
_splashes ??= HashSet<InteractiveInkFeature>();
_splashes.add(splash);
_currentSplash = splash;
+ if (widget.onTapDown != null) {
+ widget.onTapDown(details);
+ }
updateKeepAlive();
updateHighlight(_HighlightType.pressed, value: true);
}
@@ -756,37 +722,18 @@
_highlights[type]?.color = getHighlightColorForType(type);
}
_currentSplash?.color = widget.splashColor ?? Theme.of(context).splashColor;
- return Actions(
- actions: <LocalKey, ActionFactory>{
- ActivateAction.key: () {
- return CallbackAction(
- ActivateAction.key,
- onInvoke: (FocusNode node, Intent intent) {
- _startSplash(context: node.context);
- _handleTap(node.context);
- },
- );
- },
- },
- child: Focus(
- focusNode: widget.focusNode,
- canRequestFocus: widget.canRequestFocus,
- onFocusChange: _handleFocusUpdate,
- autofocus: widget.autofocus,
- child: MouseRegion(
- onEnter: enabled ? _handleMouseEnter : null,
- onExit: enabled ? _handleMouseExit : null,
- child: GestureDetector(
- onTapDown: enabled ? _handleTapDown : null,
- onTap: enabled ? () => _handleTap(context) : null,
- onTapCancel: enabled ? _handleTapCancel : null,
- onDoubleTap: widget.onDoubleTap != null ? _handleDoubleTap : null,
- onLongPress: widget.onLongPress != null ? () => _handleLongPress(context) : null,
- behavior: HitTestBehavior.opaque,
- excludeFromSemantics: widget.excludeFromSemantics,
- child: widget.child,
- ),
- ),
+ return MouseRegion(
+ onEnter: enabled ? _handleMouseEnter : null,
+ onExit: enabled ? _handleMouseExit : null,
+ child: GestureDetector(
+ onTapDown: enabled ? _handleTapDown : null,
+ onTap: enabled ? () => _handleTap(context) : null,
+ onTapCancel: enabled ? _handleTapCancel : null,
+ onDoubleTap: widget.onDoubleTap != null ? _handleDoubleTap : null,
+ onLongPress: widget.onLongPress != null ? () => _handleLongPress(context) : null,
+ behavior: HitTestBehavior.opaque,
+ child: widget.child,
+ excludeFromSemantics: widget.excludeFromSemantics,
),
);
}
@@ -907,10 +854,6 @@
ShapeBorder customBorder,
bool enableFeedback = true,
bool excludeFromSemantics = false,
- FocusNode focusNode,
- bool canRequestFocus = true,
- ValueChanged<bool> onFocusChange,
- bool autofocus = false,
}) : super(
key: key,
child: child,
@@ -933,9 +876,5 @@
customBorder: customBorder,
enableFeedback: enableFeedback ?? true,
excludeFromSemantics: excludeFromSemantics ?? false,
- focusNode: focusNode,
- canRequestFocus: canRequestFocus ?? true,
- onFocusChange: onFocusChange,
- autofocus: autofocus ?? false,
);
}
diff --git a/packages/flutter/lib/src/widgets/actions.dart b/packages/flutter/lib/src/widgets/actions.dart
index e642da2..8008ee0 100644
--- a/packages/flutter/lib/src/widgets/actions.dart
+++ b/packages/flutter/lib/src/widgets/actions.dart
@@ -345,20 +345,6 @@
}
@override
- bool operator ==(dynamic other) {
- if (other.runtimeType != runtimeType) {
- return false;
- }
- if (identical(this, other)) {
- return true;
- }
- return !updateShouldNotify(other);
- }
-
- @override
- int get hashCode => hashValues(dispatcher, actions);
-
- @override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<ActionDispatcher>('dispatcher', dispatcher));
@@ -382,16 +368,3 @@
@override
void invoke(FocusNode node, Intent intent) { }
}
-
-/// An action that invokes the currently focused control.
-///
-/// This is an abstract class that serves as a base class for actions that
-/// activate a control. It is bound to [LogicalKeyboardKey.enter] in the default
-/// keyboard map in [WidgetsApp].
-abstract class ActivateAction extends Action {
- /// Creates a [ActivateAction] with a fixed [key];
- const ActivateAction() : super(key);
-
- /// The [LocalKey] that uniquely identifies this action.
- static const LocalKey key = ValueKey<Type>(ActivateAction);
-}
diff --git a/packages/flutter/lib/src/widgets/app.dart b/packages/flutter/lib/src/widgets/app.dart
index c923c1e..9b1e990 100644
--- a/packages/flutter/lib/src/widgets/app.dart
+++ b/packages/flutter/lib/src/widgets/app.dart
@@ -7,7 +7,6 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart';
-import 'package:flutter/services.dart';
import 'actions.dart';
import 'banner.dart';
@@ -21,7 +20,6 @@
import 'pages.dart';
import 'performance_overlay.dart';
import 'semantics_debugger.dart';
-import 'shortcuts.dart';
import 'text.dart';
import 'title.dart';
import 'widget_inspector.dart';
@@ -1197,33 +1195,18 @@
assert(_debugCheckLocalizations(appLocale));
- return Shortcuts(
- shortcuts: <LogicalKeySet, Intent>{
- LogicalKeySet(LogicalKeyboardKey.tab): const Intent(NextFocusAction.key),
- LogicalKeySet(LogicalKeyboardKey.shift, LogicalKeyboardKey.tab): const Intent(PreviousFocusAction.key),
- LogicalKeySet(LogicalKeyboardKey.arrowLeft): const DirectionalFocusIntent(TraversalDirection.left),
- LogicalKeySet(LogicalKeyboardKey.arrowRight): const DirectionalFocusIntent(TraversalDirection.right),
- LogicalKeySet(LogicalKeyboardKey.arrowDown): const DirectionalFocusIntent(TraversalDirection.down),
- LogicalKeySet(LogicalKeyboardKey.arrowUp): const DirectionalFocusIntent(TraversalDirection.up),
- LogicalKeySet(LogicalKeyboardKey.enter): const Intent(ActivateAction.key),
+ return Actions(
+ actions: <LocalKey, ActionFactory>{
+ DoNothingAction.key: () => const DoNothingAction(),
},
- child: Actions(
- actions: <LocalKey, ActionFactory>{
- DoNothingAction.key: () => const DoNothingAction(),
- RequestFocusAction.key: () => RequestFocusAction(),
- NextFocusAction.key: () => NextFocusAction(),
- PreviousFocusAction.key: () => PreviousFocusAction(),
- DirectionalFocusAction.key: () => DirectionalFocusAction(),
- },
- child: DefaultFocusTraversal(
- policy: ReadingOrderTraversalPolicy(),
- child: MediaQuery(
- data: MediaQueryData.fromWindow(WidgetsBinding.instance.window),
- child: Localizations(
- locale: appLocale,
- delegates: _localizationsDelegates.toList(),
- child: title,
- ),
+ child: DefaultFocusTraversal(
+ policy: ReadingOrderTraversalPolicy(),
+ child: MediaQuery(
+ data: MediaQueryData.fromWindow(WidgetsBinding.instance.window),
+ child: Localizations(
+ locale: appLocale,
+ delegates: _localizationsDelegates.toList(),
+ child: title,
),
),
),
diff --git a/packages/flutter/lib/src/widgets/focus_scope.dart b/packages/flutter/lib/src/widgets/focus_scope.dart
index 760e97c..f829d05 100644
--- a/packages/flutter/lib/src/widgets/focus_scope.dart
+++ b/packages/flutter/lib/src/widgets/focus_scope.dart
@@ -146,11 +146,10 @@
this.onFocusChange,
this.onKey,
this.debugLabel,
- this.canRequestFocus = true,
+ this.canRequestFocus,
this.skipTraversal,
}) : assert(child != null),
assert(autofocus != null),
- assert(canRequestFocus != null),
super(key: key);
/// A debug label for this widget.
@@ -187,7 +186,7 @@
/// Handler called when the focus changes.
///
- /// Called with true if this widget's node gains focus, and false if it loses
+ /// Called with true if this node gains focus, and false if it loses
/// focus.
final ValueChanged<bool> onFocusChange;
@@ -231,7 +230,6 @@
/// still be focused explicitly.
final bool skipTraversal;
- /// {@template flutter.widgets.Focus.canRequestFocus}
/// If true, this widget may request the primary focus.
///
/// Defaults to true. Set to false if you want the [FocusNode] this widget
@@ -251,7 +249,6 @@
/// its descendants.
/// - [FocusTraversalPolicy], a class that can be extended to describe a
/// traversal policy.
- /// {@endtemplate}
final bool canRequestFocus;
/// Returns the [focusNode] of the [Focus] that most tightly encloses the
diff --git a/packages/flutter/lib/src/widgets/focus_traversal.dart b/packages/flutter/lib/src/widgets/focus_traversal.dart
index e0a8589..e063d81 100644
--- a/packages/flutter/lib/src/widgets/focus_traversal.dart
+++ b/packages/flutter/lib/src/widgets/focus_traversal.dart
@@ -2,12 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-import 'dart:ui';
-
import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart';
-import 'actions.dart';
import 'basic.dart';
import 'binding.dart';
import 'focus_manager.dart';
@@ -793,138 +790,3 @@
@override
bool updateShouldNotify(DefaultFocusTraversal oldWidget) => policy != oldWidget.policy;
}
-
-// A base class for all of the default actions that request focus for a node.
-class _RequestFocusActionBase extends Action {
- _RequestFocusActionBase(LocalKey name) : super(name);
-
- FocusNode _previousFocus;
-
- @override
- void invoke(FocusNode node, Intent tag) {
- _previousFocus = WidgetsBinding.instance.focusManager.primaryFocus;
- node.requestFocus();
- }
-
- @override
- void debugFillProperties(DiagnosticPropertiesBuilder properties) {
- super.debugFillProperties(properties);
- properties.add(DiagnosticsProperty<FocusNode>('previous', _previousFocus));
- }
-}
-
-/// An [Action] that requests the focus on the node it is invoked on.
-///
-/// This action can be used to request focus for a particular node, by calling
-/// [Action.invoke] like so:
-///
-/// ```dart
-/// Actions.invoke(context, const Intent(RequestFocusAction.key), focusNode: _focusNode);
-/// ```
-///
-/// Where the `_focusNode` is the node for which the focus will be requested.
-///
-/// The difference between requesting focus in this way versus calling
-/// [_focusNode.requestFocus] directly is that it will use the [Action]
-/// registered in the nearest [Actions] widget associated with [key] to make the
-/// request, rather than just requesting focus directly. This allows the action
-/// to have additional side effects, like logging, or undo and redo
-/// functionality.
-///
-/// However, this [RequestFocusAction] is the default action associated with the
-/// [key] in the [WidgetsApp], and it simply requests focus and has no side
-/// effects.
-class RequestFocusAction extends _RequestFocusActionBase {
- /// Creates a [RequestFocusAction] with a fixed [key].
- RequestFocusAction() : super(key);
-
- /// The [LocalKey] that uniquely identifies this action to an [Intent].
- static const LocalKey key = ValueKey<Type>(RequestFocusAction);
-
- @override
- void invoke(FocusNode node, Intent tag) {
- super.invoke(node, tag);
- node.requestFocus();
- }
-}
-
-/// An [Action] that moves the focus to the next focusable node in the focus
-/// order.
-///
-/// This action is the default action registered for the [key], and by default
-/// is bound to the [LogicalKeyboardKey.tab] key in the [WidgetsApp].
-class NextFocusAction extends _RequestFocusActionBase {
- /// Creates a [NextFocusAction] with a fixed [key];
- NextFocusAction() : super(key);
-
- /// The [LocalKey] that uniquely identifies this action to an [Intent].
- static const LocalKey key = ValueKey<Type>(NextFocusAction);
-
- @override
- void invoke(FocusNode node, Intent tag) {
- super.invoke(node, tag);
- node.nextFocus();
- }
-}
-
-/// An [Action] that moves the focus to the previous focusable node in the focus
-/// order.
-///
-/// This action is the default action registered for the [key], and by default
-/// is bound to a combination of the [LogicalKeyboardKey.tab] key and the
-/// [LogicalKeyboardKey.shift] key in the [WidgetsApp].
-class PreviousFocusAction extends _RequestFocusActionBase {
- /// Creates a [PreviousFocusAction] with a fixed [key];
- PreviousFocusAction() : super(key);
-
- /// The [LocalKey] that uniquely identifies this action to an [Intent].
- static const LocalKey key = ValueKey<Type>(PreviousFocusAction);
-
- @override
- void invoke(FocusNode node, Intent tag) {
- super.invoke(node, tag);
- node.previousFocus();
- }
-}
-
-/// An [Intent] that represents moving to the next focusable node in the given
-/// [direction].
-///
-/// This is the [Intent] bound by default to the [LogicalKeyboardKey.arrowUp],
-/// [LogicalKeyboardKey.arrowDown], [LogicalKeyboardKey.arrowLeft], and
-/// [LogicalKeyboardKey.arrowRight] keys in the [WidgetsApp], with the
-/// appropriate associated directions.
-class DirectionalFocusIntent extends Intent {
- /// Creates a [DirectionalFocusIntent] with a fixed [key], and the given
- /// [direction].
- const DirectionalFocusIntent(this.direction) : super(DirectionalFocusAction.key);
-
- /// The direction in which to look for the next focusable node when the
- /// associated [DirectionalFocusAction] is invoked.
- final TraversalDirection direction;
-}
-
-/// An [Action] that moves the focus to the focusable node in the given
-/// [direction] configured by the associated [DirectionalFocusIntent].
-///
-/// This is the [Action] associated with the [key] and bound by default to the
-/// [LogicalKeyboardKey.arrowUp], [LogicalKeyboardKey.arrowDown],
-/// [LogicalKeyboardKey.arrowLeft], and [LogicalKeyboardKey.arrowRight] keys in
-/// the [WidgetsApp], with the appropriate associated directions.
-class DirectionalFocusAction extends _RequestFocusActionBase {
- /// Creates a [DirectionalFocusAction] with a fixed [key];
- DirectionalFocusAction() : super(key);
-
- /// The [LocalKey] that uniquely identifies this action to [DirectionalFocusIntent].
- static const LocalKey key = ValueKey<Type>(DirectionalFocusAction);
-
- /// The direction in which to look for the next focusable node when invoked.
- TraversalDirection direction;
-
- @override
- void invoke(FocusNode node, DirectionalFocusIntent tag) {
- super.invoke(node, tag);
- final DirectionalFocusIntent args = tag;
- node.focusInDirection(args.direction);
- }
-}
diff --git a/packages/flutter/test/material/ink_paint_test.dart b/packages/flutter/test/material/ink_paint_test.dart
index 643f814..03cd7c1 100644
--- a/packages/flutter/test/material/ink_paint_test.dart
+++ b/packages/flutter/test/material/ink_paint_test.dart
@@ -4,7 +4,6 @@
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
-import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import '../rendering/mock_canvas.dart';
@@ -128,21 +127,17 @@
..translate(x: 0.0, y: 0.0)
..translate(x: tapDownOffset.dx, y: tapDownOffset.dy)
..something((Symbol method, List<dynamic> arguments) {
- if (method != #drawCircle) {
+ if (method != #drawCircle)
return false;
- }
final Offset center = arguments[0];
final double radius = arguments[1];
final Paint paint = arguments[2];
- if (offsetsAreClose(center, expectedCenter) &&
- radiiAreClose(radius, expectedRadius) &&
- paint.color.alpha == expectedAlpha) {
+ if (offsetsAreClose(center, expectedCenter) && radiiAreClose(radius, expectedRadius) && paint.color.alpha == expectedAlpha)
return true;
- }
throw '''
Expected: center == $expectedCenter, radius == $expectedRadius, alpha == $expectedAlpha
Found: center == $center radius == $radius alpha == ${paint.color.alpha}''';
- },
+ }
);
}
@@ -256,102 +251,6 @@
await gesture.up();
}, skip: isBrowser);
- testWidgets('The InkWell widget renders an ActivateAction-induced ink ripple', (WidgetTester tester) async {
- const Color highlightColor = Color(0xAAFF0000);
- const Color splashColor = Color(0xB40000FF);
- final BorderRadius borderRadius = BorderRadius.circular(6.0);
-
- final FocusNode focusNode = FocusNode(debugLabel: 'Test Node');
- await tester.pumpWidget(
- Shortcuts(
- shortcuts: <LogicalKeySet, Intent>{
- LogicalKeySet(LogicalKeyboardKey.enter): const Intent(ActivateAction.key),
- },
- child: Directionality(
- textDirection: TextDirection.ltr,
- child: Material(
- child: Center(
- child: Container(
- width: 100.0,
- height: 100.0,
- child: InkWell(
- borderRadius: borderRadius,
- highlightColor: highlightColor,
- splashColor: splashColor,
- focusNode: focusNode,
- onTap: () { },
- radius: 100.0,
- splashFactory: InkRipple.splashFactory,
- ),
- ),
- ),
- ),
- ),
- ),
- );
-
- final Offset topLeft = tester.getTopLeft(find.byType(InkWell));
- final Offset inkWellCenter = tester.getCenter(find.byType(InkWell)) - topLeft;
-
- // Now activate it with a keypress.
- focusNode.requestFocus();
- await tester.pumpAndSettle();
-
- await tester.sendKeyEvent(LogicalKeyboardKey.enter);
- await tester.pump();
-
- final RenderBox box = Material.of(tester.element(find.byType(InkWell))) as dynamic;
-
- bool offsetsAreClose(Offset a, Offset b) => (a - b).distance < 1.0;
- bool radiiAreClose(double a, double b) => (a - b).abs() < 1.0;
-
- PaintPattern ripplePattern(double expectedRadius, int expectedAlpha) {
- return paints
- ..translate(x: 0.0, y: 0.0)
- ..translate(x: topLeft.dx, y: topLeft.dy)
- ..something((Symbol method, List<dynamic> arguments) {
- if (method != #drawCircle) {
- return false;
- }
- final Offset center = arguments[0];
- final double radius = arguments[1];
- final Paint paint = arguments[2];
- if (offsetsAreClose(center, inkWellCenter) &&
- radiiAreClose(radius, expectedRadius) &&
- paint.color.alpha == expectedAlpha) {
- return true;
- }
- throw '''
- Expected: center == $inkWellCenter, radius == $expectedRadius, alpha == $expectedAlpha
- Found: center == $center radius == $radius alpha == ${paint.color.alpha}''';
- },
- );
- }
-
- // ripplePattern always add a translation of topLeft.
- expect(box, ripplePattern(30.0, 0));
-
- // The ripple fades in for 75ms. During that time its alpha is eased from
- // 0 to the splashColor's alpha value.
- await tester.pump(const Duration(milliseconds: 50));
- expect(box, ripplePattern(56.0, 120));
-
- // At 75ms the ripple has faded in: it's alpha matches the splashColor's
- // alpha.
- await tester.pump(const Duration(milliseconds: 25));
- expect(box, ripplePattern(73.0, 180));
-
- // At this point the splash radius has expanded to its limit: 5 past the
- // ink well's radius parameter. The fade-out is about to start.
- // The fade-out begins at 225ms = 50ms + 25ms + 150ms.
- await tester.pump(const Duration(milliseconds: 150));
- expect(box, ripplePattern(105.0, 180));
-
- // After another 150ms the fade-out is complete.
- await tester.pump(const Duration(milliseconds: 150));
- expect(box, ripplePattern(105.0, 0));
- });
-
testWidgets('Cancel an InkRipple that was disposed when its animation ended', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/14391
await tester.pumpWidget(
@@ -432,4 +331,5 @@
throw 'Expected: paint.color.alpha == 0, found: ${paint.color.alpha}';
}));
});
+
}
diff --git a/packages/flutter/test/material/ink_well_test.dart b/packages/flutter/test/material/ink_well_test.dart
index dfad562..9b4a8f9 100644
--- a/packages/flutter/test/material/ink_well_test.dart
+++ b/packages/flutter/test/material/ink_well_test.dart
@@ -103,9 +103,9 @@
splashColor: const Color(0xffff0000),
focusColor: const Color(0xff0000ff),
highlightColor: const Color(0xf00fffff),
- onTap: () { },
- onLongPress: () { },
- onHover: (bool hover) { },
+ onTap: () {},
+ onLongPress: () {},
+ onHover: (bool hover) {},
),
),
),
@@ -123,29 +123,29 @@
testWidgets('ink response changes color on focus', (WidgetTester tester) async {
WidgetsBinding.instance.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
final FocusNode focusNode = FocusNode(debugLabel: 'Ink Focus');
- await tester.pumpWidget(
- Material(
- child: Directionality(
- textDirection: TextDirection.ltr,
- child: Center(
+ await tester.pumpWidget(Material(
+ child: Directionality(
+ textDirection: TextDirection.ltr,
+ child: Center(
+ child: Focus(
+ focusNode: focusNode,
child: Container(
width: 100,
height: 100,
child: InkWell(
- focusNode: focusNode,
hoverColor: const Color(0xff00ff00),
splashColor: const Color(0xffff0000),
focusColor: const Color(0xff0000ff),
highlightColor: const Color(0xf00fffff),
- onTap: () { },
- onLongPress: () { },
- onHover: (bool hover) { },
+ onTap: () {},
+ onLongPress: () {},
+ onHover: (bool hover) {},
),
),
),
),
),
- );
+ ));
await tester.pumpAndSettle();
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
expect(inkFeatures, paintsExactlyCountTimes(#rect, 0));
@@ -172,9 +172,9 @@
splashColor: const Color(0xffff0000),
focusColor: const Color(0xff0000ff),
highlightColor: const Color(0xf00fffff),
- onTap: () { },
- onLongPress: () { },
- onHover: (bool hover) { },
+ onTap: () {},
+ onLongPress: () {},
+ onHover: (bool hover) {},
),
),
),
@@ -206,8 +206,8 @@
textDirection: TextDirection.ltr,
child: Center(
child: InkWell(
- onTap: () { },
- onLongPress: () { },
+ onTap: () {},
+ onLongPress: () {},
),
),
),
@@ -234,8 +234,8 @@
textDirection: TextDirection.ltr,
child: Center(
child: InkWell(
- onTap: () { },
- onLongPress: () { },
+ onTap: () {},
+ onLongPress: () {},
enableFeedback: false,
),
),
@@ -301,7 +301,7 @@
textDirection: TextDirection.ltr,
child: Material(
child: InkWell(
- onTap: () { },
+ onTap: () {},
child: const Text('Button'),
),
),
@@ -312,7 +312,7 @@
textDirection: TextDirection.ltr,
child: Material(
child: InkWell(
- onTap: () { },
+ onTap: () {},
child: const Text('Button'),
excludeFromSemantics: true,
),
diff --git a/packages/flutter/test/material/raw_material_button_test.dart b/packages/flutter/test/material/raw_material_button_test.dart
index 074f3da..bed44b0 100644
--- a/packages/flutter/test/material/raw_material_button_test.dart
+++ b/packages/flutter/test/material/raw_material_button_test.dart
@@ -5,77 +5,12 @@
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
-import 'package:flutter/src/services/keyboard_key.dart';
import 'package:flutter_test/flutter_test.dart';
import '../rendering/mock_canvas.dart';
import '../widgets/semantics_tester.dart';
void main() {
- testWidgets('RawMaterialButton responds when tapped', (WidgetTester tester) async {
- bool pressed = false;
- const Color splashColor = Color(0xff00ff00);
- await tester.pumpWidget(
- Directionality(
- textDirection: TextDirection.ltr,
- child: Center(
- child: RawMaterialButton(
- splashColor: splashColor,
- onPressed: () { pressed = true; },
- child: const Text('BUTTON'),
- ),
- ),
- ),
- );
-
- await tester.tap(find.text('BUTTON'));
- await tester.pump(const Duration(milliseconds: 10));
-
- final RenderBox splash = Material.of(tester.element(find.byType(InkWell))) as dynamic;
- expect(splash, paints..circle(color: splashColor));
-
- await tester.pumpAndSettle();
-
- expect(pressed, isTrue);
- });
-
- testWidgets('RawMaterialButton responds to shortcut when activated', (WidgetTester tester) async {
- bool pressed = false;
- final FocusNode focusNode = FocusNode(debugLabel: 'Test Button');
- const Color splashColor = Color(0xff00ff00);
- await tester.pumpWidget(
- Shortcuts(
- shortcuts: <LogicalKeySet, Intent>{
- LogicalKeySet(LogicalKeyboardKey.enter): const Intent(ActivateAction.key),
- },
- child: Directionality(
- textDirection: TextDirection.ltr,
- child: Center(
- child: RawMaterialButton(
- splashColor: splashColor,
- focusNode: focusNode,
- onPressed: () { pressed = true; },
- child: const Text('BUTTON'),
- ),
- ),
- ),
- ),
- );
-
- focusNode.requestFocus();
- await tester.pump();
-
- await tester.sendKeyEvent(LogicalKeyboardKey.enter);
- await tester.pump(const Duration(milliseconds: 10));
-
- final RenderBox splash = Material.of(tester.element(find.byType(InkWell))) as dynamic;
- expect(splash, paints..circle(color: splashColor));
-
- await tester.pumpAndSettle();
-
- expect(pressed, isTrue);
- });
-
testWidgets('materialTapTargetSize.padded expands hit test area', (WidgetTester tester) async {
int pressed = 0;
diff --git a/packages/flutter/test/widgets/actions_test.dart b/packages/flutter/test/widgets/actions_test.dart
index 9533598..1a7454f 100644
--- a/packages/flutter/test/widgets/actions_test.dart
+++ b/packages/flutter/test/widgets/actions_test.dart
@@ -324,11 +324,11 @@
).debugFillProperties(builder);
final List<String> description = builder.properties
- .where((DiagnosticsNode node) {
- return !node.isFiltered(DiagnosticLevel.info);
- })
- .map((DiagnosticsNode node) => node.toString())
- .toList();
+ .where((DiagnosticsNode node) {
+ return !node.isFiltered(DiagnosticLevel.info);
+ })
+ .map((DiagnosticsNode node) => node.toString())
+ .toList();
expect(description[0], equalsIgnoringHashCodes('dispatcher: ActionDispatcher#00000'));
expect(description[1], equals('actions: {[<\'bar\'>]: Closure: () => TestAction}'));
diff --git a/packages/flutter/test/widgets/focus_traversal_test.dart b/packages/flutter/test/widgets/focus_traversal_test.dart
index bfc7824..b2ce03b 100644
--- a/packages/flutter/test/widgets/focus_traversal_test.dart
+++ b/packages/flutter/test/widgets/focus_traversal_test.dart
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-import 'package:flutter/painting.dart';
-import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
@@ -916,112 +914,5 @@
expect(focusCenter.hasFocus, isFalse);
expect(focusTop.hasFocus, isTrue);
});
- testWidgets('Focus traversal actions are invoked when shortcuts are used.', (WidgetTester tester) async {
- final GlobalKey upperLeftKey = GlobalKey(debugLabel: 'upperLeftKey');
- final GlobalKey upperRightKey = GlobalKey(debugLabel: 'upperRightKey');
- final GlobalKey lowerLeftKey = GlobalKey(debugLabel: 'lowerLeftKey');
- final GlobalKey lowerRightKey = GlobalKey(debugLabel: 'lowerRightKey');
-
- await tester.pumpWidget(
- WidgetsApp(
- color: const Color(0xFFFFFFFF),
- onGenerateRoute: (RouteSettings settings) {
- return TestRoute(
- child: Directionality(
- textDirection: TextDirection.ltr,
- child: FocusScope(
- debugLabel: 'scope',
- child: Column(
- children: <Widget>[
- Row(
- children: <Widget>[
- Focus(
- autofocus: true,
- debugLabel: 'upperLeft',
- child: Container(width: 100, height: 100, key: upperLeftKey),
- ),
- Focus(
- debugLabel: 'upperRight',
- child: Container(width: 100, height: 100, key: upperRightKey),
- ),
- ],
- ),
- Row(
- children: <Widget>[
- Focus(
- debugLabel: 'lowerLeft',
- child: Container(width: 100, height: 100, key: lowerLeftKey),
- ),
- Focus(
- debugLabel: 'lowerRight',
- child: Container(width: 100, height: 100, key: lowerRightKey),
- ),
- ],
- ),
- ],
- ),
- ),
- ),
- );
- },
- ),
- );
-
- // Initial focus happens.
- expect(Focus.of(upperLeftKey.currentContext).hasPrimaryFocus, isTrue);
- await tester.sendKeyEvent(LogicalKeyboardKey.tab);
- expect(Focus.of(upperRightKey.currentContext).hasPrimaryFocus, isTrue);
- // Initial focus happens.
- await tester.sendKeyEvent(LogicalKeyboardKey.tab);
- expect(Focus.of(lowerLeftKey.currentContext).hasPrimaryFocus, isTrue);
- // Initial focus happens.
- await tester.sendKeyEvent(LogicalKeyboardKey.tab);
- expect(Focus.of(lowerRightKey.currentContext).hasPrimaryFocus, isTrue);
- // Initial focus happens.
- await tester.sendKeyEvent(LogicalKeyboardKey.tab);
- expect(Focus.of(upperLeftKey.currentContext).hasPrimaryFocus, isTrue);
-
- await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
- await tester.sendKeyEvent(LogicalKeyboardKey.tab);
- await tester.sendKeyUpEvent(LogicalKeyboardKey.shift);
- expect(Focus.of(lowerRightKey.currentContext).hasPrimaryFocus, isTrue);
- // Initial focus happens.
- await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
- await tester.sendKeyEvent(LogicalKeyboardKey.tab);
- await tester.sendKeyUpEvent(LogicalKeyboardKey.shift);
- expect(Focus.of(lowerLeftKey.currentContext).hasPrimaryFocus, isTrue);
- // Initial focus happens.
- await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
- await tester.sendKeyEvent(LogicalKeyboardKey.tab);
- await tester.sendKeyUpEvent(LogicalKeyboardKey.shift);
- expect(Focus.of(upperRightKey.currentContext).hasPrimaryFocus, isTrue);
- // Initial focus happens.
- await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
- await tester.sendKeyEvent(LogicalKeyboardKey.tab);
- await tester.sendKeyUpEvent(LogicalKeyboardKey.shift);
- expect(Focus.of(upperLeftKey.currentContext).hasPrimaryFocus, isTrue);
-
- // Traverse in a direction
- await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
- expect(Focus.of(upperRightKey.currentContext).hasPrimaryFocus, isTrue);
- // Initial focus happens.
- await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
- expect(Focus.of(lowerRightKey.currentContext).hasPrimaryFocus, isTrue);
- // Initial focus happens.
- await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft);
- expect(Focus.of(lowerLeftKey.currentContext).hasPrimaryFocus, isTrue);
- // Initial focus happens.
- await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
- expect(Focus.of(upperLeftKey.currentContext).hasPrimaryFocus, isTrue);
- });
});
}
-
-class TestRoute extends PageRouteBuilder<void> {
- TestRoute({Widget child})
- : super(
- pageBuilder: (BuildContext _, Animation<double> __, Animation<double> ___) {
- return child;
- },
- );
-}