Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
d2c8b623
Unverified
Commit
d2c8b623
authored
Sep 28, 2021
by
yk3372
Committed by
GitHub
Sep 28, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
make Elevated&Outlined&TextButton support onHover&onFocus callback (#90688)
parent
a16b8263
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
576 additions
and
2 deletions
+576
-2
AUTHORS
AUTHORS
+1
-0
button_style_button.dart
packages/flutter/lib/src/material/button_style_button.dart
+23
-2
elevated_button.dart
packages/flutter/lib/src/material/elevated_button.dart
+10
-0
outlined_button.dart
packages/flutter/lib/src/material/outlined_button.dart
+4
-0
text_button.dart
packages/flutter/lib/src/material/text_button.dart
+10
-0
elevated_button_test.dart
packages/flutter/test/material/elevated_button_test.dart
+176
-0
outlined_button_test.dart
packages/flutter/test/material/outlined_button_test.dart
+176
-0
text_button_test.dart
packages/flutter/test/material/text_button_test.dart
+176
-0
No files found.
AUTHORS
View file @
d2c8b623
...
@@ -85,3 +85,4 @@ Callum Moffat <callum@moffatman.com>
...
@@ -85,3 +85,4 @@ Callum Moffat <callum@moffatman.com>
Koutaro Mori <koutaro.mo@gmail.com>
Koutaro Mori <koutaro.mo@gmail.com>
Sergei Smitskoi <sergflutterdev@gmail.com>
Sergei Smitskoi <sergflutterdev@gmail.com>
Pradumna Saraf <pradumnasaraf@gmail.com>
Pradumna Saraf <pradumnasaraf@gmail.com>
Kai Yu <yk3372@gmail.com>
packages/flutter/lib/src/material/button_style_button.dart
View file @
d2c8b623
...
@@ -33,6 +33,8 @@ abstract class ButtonStyleButton extends StatefulWidget {
...
@@ -33,6 +33,8 @@ abstract class ButtonStyleButton extends StatefulWidget {
Key
?
key
,
Key
?
key
,
required
this
.
onPressed
,
required
this
.
onPressed
,
required
this
.
onLongPress
,
required
this
.
onLongPress
,
required
this
.
onHover
,
required
this
.
onFocusChange
,
required
this
.
style
,
required
this
.
style
,
required
this
.
focusNode
,
required
this
.
focusNode
,
required
this
.
autofocus
,
required
this
.
autofocus
,
...
@@ -60,6 +62,19 @@ abstract class ButtonStyleButton extends StatefulWidget {
...
@@ -60,6 +62,19 @@ abstract class ButtonStyleButton extends StatefulWidget {
/// * [enabled], which is true if the button is enabled.
/// * [enabled], which is true if the button is enabled.
final
VoidCallback
?
onLongPress
;
final
VoidCallback
?
onLongPress
;
/// Called when a pointer enters or exits the button response area.
///
/// The value passed to the callback is true if a pointer has entered this
/// part of the material and false if a pointer has exited this part of the
/// material.
final
ValueChanged
<
bool
>?
onHover
;
/// 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
;
/// Customizes this button's appearance.
/// Customizes this button's appearance.
///
///
/// Non-null properties of this style override the corresponding
/// Non-null properties of this style override the corresponding
...
@@ -335,12 +350,18 @@ class _ButtonStyleState extends State<ButtonStyleButton> with MaterialStateMixin
...
@@ -335,12 +350,18 @@ class _ButtonStyleState extends State<ButtonStyleButton> with MaterialStateMixin
onTap:
widget
.
onPressed
,
onTap:
widget
.
onPressed
,
onLongPress:
widget
.
onLongPress
,
onLongPress:
widget
.
onLongPress
,
onHighlightChanged:
updateMaterialState
(
MaterialState
.
pressed
),
onHighlightChanged:
updateMaterialState
(
MaterialState
.
pressed
),
onHover:
updateMaterialState
(
MaterialState
.
hovered
),
onHover:
updateMaterialState
(
MaterialState
.
hovered
,
onChanged:
widget
.
onHover
,
),
mouseCursor:
resolvedMouseCursor
,
mouseCursor:
resolvedMouseCursor
,
enableFeedback:
resolvedEnableFeedback
,
enableFeedback:
resolvedEnableFeedback
,
focusNode:
widget
.
focusNode
,
focusNode:
widget
.
focusNode
,
canRequestFocus:
widget
.
enabled
,
canRequestFocus:
widget
.
enabled
,
onFocusChange:
updateMaterialState
(
MaterialState
.
focused
),
onFocusChange:
updateMaterialState
(
MaterialState
.
focused
,
onChanged:
widget
.
onFocusChange
,
),
autofocus:
widget
.
autofocus
,
autofocus:
widget
.
autofocus
,
splashFactory:
resolvedSplashFactory
,
splashFactory:
resolvedSplashFactory
,
overlayColor:
overlayColor
,
overlayColor:
overlayColor
,
...
...
packages/flutter/lib/src/material/elevated_button.dart
View file @
d2c8b623
...
@@ -65,6 +65,8 @@ class ElevatedButton extends ButtonStyleButton {
...
@@ -65,6 +65,8 @@ class ElevatedButton extends ButtonStyleButton {
Key
?
key
,
Key
?
key
,
required
VoidCallback
?
onPressed
,
required
VoidCallback
?
onPressed
,
VoidCallback
?
onLongPress
,
VoidCallback
?
onLongPress
,
ValueChanged
<
bool
>?
onHover
,
ValueChanged
<
bool
>?
onFocusChange
,
ButtonStyle
?
style
,
ButtonStyle
?
style
,
FocusNode
?
focusNode
,
FocusNode
?
focusNode
,
bool
autofocus
=
false
,
bool
autofocus
=
false
,
...
@@ -74,6 +76,8 @@ class ElevatedButton extends ButtonStyleButton {
...
@@ -74,6 +76,8 @@ class ElevatedButton extends ButtonStyleButton {
key:
key
,
key:
key
,
onPressed:
onPressed
,
onPressed:
onPressed
,
onLongPress:
onLongPress
,
onLongPress:
onLongPress
,
onHover:
onHover
,
onFocusChange:
onFocusChange
,
style:
style
,
style:
style
,
focusNode:
focusNode
,
focusNode:
focusNode
,
autofocus:
autofocus
,
autofocus:
autofocus
,
...
@@ -92,6 +96,8 @@ class ElevatedButton extends ButtonStyleButton {
...
@@ -92,6 +96,8 @@ class ElevatedButton extends ButtonStyleButton {
Key
?
key
,
Key
?
key
,
required
VoidCallback
?
onPressed
,
required
VoidCallback
?
onPressed
,
VoidCallback
?
onLongPress
,
VoidCallback
?
onLongPress
,
ValueChanged
<
bool
>?
onHover
,
ValueChanged
<
bool
>?
onFocusChange
,
ButtonStyle
?
style
,
ButtonStyle
?
style
,
FocusNode
?
focusNode
,
FocusNode
?
focusNode
,
bool
?
autofocus
,
bool
?
autofocus
,
...
@@ -399,6 +405,8 @@ class _ElevatedButtonWithIcon extends ElevatedButton {
...
@@ -399,6 +405,8 @@ class _ElevatedButtonWithIcon extends ElevatedButton {
Key
?
key
,
Key
?
key
,
required
VoidCallback
?
onPressed
,
required
VoidCallback
?
onPressed
,
VoidCallback
?
onLongPress
,
VoidCallback
?
onLongPress
,
ValueChanged
<
bool
>?
onHover
,
ValueChanged
<
bool
>?
onFocusChange
,
ButtonStyle
?
style
,
ButtonStyle
?
style
,
FocusNode
?
focusNode
,
FocusNode
?
focusNode
,
bool
?
autofocus
,
bool
?
autofocus
,
...
@@ -411,6 +419,8 @@ class _ElevatedButtonWithIcon extends ElevatedButton {
...
@@ -411,6 +419,8 @@ class _ElevatedButtonWithIcon extends ElevatedButton {
key:
key
,
key:
key
,
onPressed:
onPressed
,
onPressed:
onPressed
,
onLongPress:
onLongPress
,
onLongPress:
onLongPress
,
onHover:
onHover
,
onFocusChange:
onFocusChange
,
style:
style
,
style:
style
,
focusNode:
focusNode
,
focusNode:
focusNode
,
autofocus:
autofocus
??
false
,
autofocus:
autofocus
??
false
,
...
...
packages/flutter/lib/src/material/outlined_button.dart
View file @
d2c8b623
...
@@ -70,6 +70,8 @@ class OutlinedButton extends ButtonStyleButton {
...
@@ -70,6 +70,8 @@ class OutlinedButton extends ButtonStyleButton {
Key
?
key
,
Key
?
key
,
required
VoidCallback
?
onPressed
,
required
VoidCallback
?
onPressed
,
VoidCallback
?
onLongPress
,
VoidCallback
?
onLongPress
,
ValueChanged
<
bool
>?
onHover
,
ValueChanged
<
bool
>?
onFocusChange
,
ButtonStyle
?
style
,
ButtonStyle
?
style
,
FocusNode
?
focusNode
,
FocusNode
?
focusNode
,
bool
autofocus
=
false
,
bool
autofocus
=
false
,
...
@@ -79,6 +81,8 @@ class OutlinedButton extends ButtonStyleButton {
...
@@ -79,6 +81,8 @@ class OutlinedButton extends ButtonStyleButton {
key:
key
,
key:
key
,
onPressed:
onPressed
,
onPressed:
onPressed
,
onLongPress:
onLongPress
,
onLongPress:
onLongPress
,
onHover:
onHover
,
onFocusChange:
onFocusChange
,
style:
style
,
style:
style
,
focusNode:
focusNode
,
focusNode:
focusNode
,
autofocus:
autofocus
,
autofocus:
autofocus
,
...
...
packages/flutter/lib/src/material/text_button.dart
View file @
d2c8b623
...
@@ -70,6 +70,8 @@ class TextButton extends ButtonStyleButton {
...
@@ -70,6 +70,8 @@ class TextButton extends ButtonStyleButton {
Key
?
key
,
Key
?
key
,
required
VoidCallback
?
onPressed
,
required
VoidCallback
?
onPressed
,
VoidCallback
?
onLongPress
,
VoidCallback
?
onLongPress
,
ValueChanged
<
bool
>?
onHover
,
ValueChanged
<
bool
>?
onFocusChange
,
ButtonStyle
?
style
,
ButtonStyle
?
style
,
FocusNode
?
focusNode
,
FocusNode
?
focusNode
,
bool
autofocus
=
false
,
bool
autofocus
=
false
,
...
@@ -79,6 +81,8 @@ class TextButton extends ButtonStyleButton {
...
@@ -79,6 +81,8 @@ class TextButton extends ButtonStyleButton {
key:
key
,
key:
key
,
onPressed:
onPressed
,
onPressed:
onPressed
,
onLongPress:
onLongPress
,
onLongPress:
onLongPress
,
onHover:
onHover
,
onFocusChange:
onFocusChange
,
style:
style
,
style:
style
,
focusNode:
focusNode
,
focusNode:
focusNode
,
autofocus:
autofocus
,
autofocus:
autofocus
,
...
@@ -97,6 +101,8 @@ class TextButton extends ButtonStyleButton {
...
@@ -97,6 +101,8 @@ class TextButton extends ButtonStyleButton {
Key
?
key
,
Key
?
key
,
required
VoidCallback
?
onPressed
,
required
VoidCallback
?
onPressed
,
VoidCallback
?
onLongPress
,
VoidCallback
?
onLongPress
,
ValueChanged
<
bool
>?
onHover
,
ValueChanged
<
bool
>?
onFocusChange
,
ButtonStyle
?
style
,
ButtonStyle
?
style
,
FocusNode
?
focusNode
,
FocusNode
?
focusNode
,
bool
?
autofocus
,
bool
?
autofocus
,
...
@@ -362,6 +368,8 @@ class _TextButtonWithIcon extends TextButton {
...
@@ -362,6 +368,8 @@ class _TextButtonWithIcon extends TextButton {
Key
?
key
,
Key
?
key
,
required
VoidCallback
?
onPressed
,
required
VoidCallback
?
onPressed
,
VoidCallback
?
onLongPress
,
VoidCallback
?
onLongPress
,
ValueChanged
<
bool
>?
onHover
,
ValueChanged
<
bool
>?
onFocusChange
,
ButtonStyle
?
style
,
ButtonStyle
?
style
,
FocusNode
?
focusNode
,
FocusNode
?
focusNode
,
bool
?
autofocus
,
bool
?
autofocus
,
...
@@ -374,6 +382,8 @@ class _TextButtonWithIcon extends TextButton {
...
@@ -374,6 +382,8 @@ class _TextButtonWithIcon extends TextButton {
key:
key
,
key:
key
,
onPressed:
onPressed
,
onPressed:
onPressed
,
onLongPress:
onLongPress
,
onLongPress:
onLongPress
,
onHover:
onHover
,
onFocusChange:
onFocusChange
,
style:
style
,
style:
style
,
focusNode:
focusNode
,
focusNode:
focusNode
,
autofocus:
autofocus
??
false
,
autofocus:
autofocus
??
false
,
...
...
packages/flutter/test/material/elevated_button_test.dart
View file @
d2c8b623
...
@@ -414,6 +414,182 @@ void main() {
...
@@ -414,6 +414,182 @@ void main() {
expect
(
didLongPressButton
,
isTrue
);
expect
(
didLongPressButton
,
isTrue
);
});
});
testWidgets
(
"ElevatedButton response doesn't hover when disabled"
,
(
WidgetTester
tester
)
async
{
FocusManager
.
instance
.
highlightStrategy
=
FocusHighlightStrategy
.
alwaysTouch
;
final
FocusNode
focusNode
=
FocusNode
(
debugLabel:
'ElevatedButton Focus'
);
final
GlobalKey
childKey
=
GlobalKey
();
bool
hovering
=
false
;
await
tester
.
pumpWidget
(
Material
(
child:
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
SizedBox
(
width:
100
,
height:
100
,
child:
ElevatedButton
(
autofocus:
true
,
onPressed:
()
{},
onLongPress:
()
{},
onHover:
(
bool
value
)
{
hovering
=
value
;
},
focusNode:
focusNode
,
child:
SizedBox
(
key:
childKey
),
),
),
),
),
);
await
tester
.
pumpAndSettle
();
expect
(
focusNode
.
hasPrimaryFocus
,
isTrue
);
final
TestGesture
gesture
=
await
tester
.
createGesture
(
kind:
PointerDeviceKind
.
mouse
);
await
gesture
.
addPointer
();
addTearDown
(
gesture
.
removePointer
);
await
gesture
.
moveTo
(
tester
.
getCenter
(
find
.
byKey
(
childKey
)));
await
tester
.
pumpAndSettle
();
expect
(
hovering
,
isTrue
);
await
tester
.
pumpWidget
(
Material
(
child:
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
SizedBox
(
width:
100
,
height:
100
,
child:
ElevatedButton
(
focusNode:
focusNode
,
onHover:
(
bool
value
)
{
hovering
=
value
;
},
onPressed:
null
,
child:
SizedBox
(
key:
childKey
),
),
),
),
),
);
await
tester
.
pumpAndSettle
();
expect
(
focusNode
.
hasPrimaryFocus
,
isFalse
);
});
testWidgets
(
'disabled and hovered ElevatedButton responds to mouse-exit'
,
(
WidgetTester
tester
)
async
{
int
onHoverCount
=
0
;
late
bool
hover
;
Widget
buildFrame
({
required
bool
enabled
})
{
return
Material
(
child:
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
Center
(
child:
SizedBox
(
width:
100
,
height:
100
,
child:
ElevatedButton
(
onPressed:
enabled
?
()
{
}
:
null
,
onHover:
(
bool
value
)
{
onHoverCount
+=
1
;
hover
=
value
;
},
child:
const
Text
(
'ElevatedButton'
),
),
),
),
),
);
}
await
tester
.
pumpWidget
(
buildFrame
(
enabled:
true
));
final
TestGesture
gesture
=
await
tester
.
createGesture
(
kind:
PointerDeviceKind
.
mouse
);
await
gesture
.
addPointer
();
addTearDown
(
gesture
.
removePointer
);
await
gesture
.
moveTo
(
tester
.
getCenter
(
find
.
byType
(
ElevatedButton
)));
await
tester
.
pumpAndSettle
();
expect
(
onHoverCount
,
1
);
expect
(
hover
,
true
);
await
tester
.
pumpWidget
(
buildFrame
(
enabled:
false
));
await
tester
.
pumpAndSettle
();
await
gesture
.
moveTo
(
Offset
.
zero
);
// Even though the ElevatedButton has been disabled, the mouse-exit still
// causes onHover(false) to be called.
expect
(
onHoverCount
,
2
);
expect
(
hover
,
false
);
await
gesture
.
moveTo
(
tester
.
getCenter
(
find
.
byType
(
ElevatedButton
)));
await
tester
.
pumpAndSettle
();
// We no longer see hover events because the ElevatedButton is disabled
// and it's no longer in the "hovering" state.
expect
(
onHoverCount
,
2
);
expect
(
hover
,
false
);
await
tester
.
pumpWidget
(
buildFrame
(
enabled:
true
));
await
tester
.
pumpAndSettle
();
// The ElevatedButton was enabled while it contained the mouse, however
// we do not call onHover() because it may call setState().
expect
(
onHoverCount
,
2
);
expect
(
hover
,
false
);
await
gesture
.
moveTo
(
tester
.
getCenter
(
find
.
byType
(
ElevatedButton
))
-
const
Offset
(
1
,
1
));
await
tester
.
pumpAndSettle
();
// Moving the mouse a little within the ElevatedButton doesn't change anything.
expect
(
onHoverCount
,
2
);
expect
(
hover
,
false
);
});
testWidgets
(
'Can set ElevatedButton focus and Can set unFocus.'
,
(
WidgetTester
tester
)
async
{
final
FocusNode
node
=
FocusNode
(
debugLabel:
'ElevatedButton Focus'
);
bool
gotFocus
=
false
;
await
tester
.
pumpWidget
(
Material
(
child:
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
ElevatedButton
(
focusNode:
node
,
onFocusChange:
(
bool
focused
)
=>
gotFocus
=
focused
,
onPressed:
()
{
},
child:
const
SizedBox
(),
),
),
),
);
node
.
requestFocus
();
await
tester
.
pump
();
expect
(
gotFocus
,
isTrue
);
expect
(
node
.
hasFocus
,
isTrue
);
node
.
unfocus
();
await
tester
.
pump
();
expect
(
gotFocus
,
isFalse
);
expect
(
node
.
hasFocus
,
isFalse
);
});
testWidgets
(
'When ElevatedButton disable, Can not set ElevatedButton focus.'
,
(
WidgetTester
tester
)
async
{
final
FocusNode
node
=
FocusNode
(
debugLabel:
'ElevatedButton Focus'
);
bool
gotFocus
=
false
;
await
tester
.
pumpWidget
(
Material
(
child:
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
ElevatedButton
(
focusNode:
node
,
onFocusChange:
(
bool
focused
)
=>
gotFocus
=
focused
,
onPressed:
null
,
child:
const
SizedBox
(),
),
),
),
);
node
.
requestFocus
();
await
tester
.
pump
();
expect
(
gotFocus
,
isFalse
);
expect
(
node
.
hasFocus
,
isFalse
);
});
testWidgets
(
'Does ElevatedButton work with hover'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'Does ElevatedButton work with hover'
,
(
WidgetTester
tester
)
async
{
const
Color
hoverColor
=
Color
(
0xff001122
);
const
Color
hoverColor
=
Color
(
0xff001122
);
...
...
packages/flutter/test/material/outlined_button_test.dart
View file @
d2c8b623
...
@@ -613,6 +613,182 @@ void main() {
...
@@ -613,6 +613,182 @@ void main() {
expect
(
tester
.
widget
<
OutlinedButton
>(
outlinedButton
).
enabled
,
false
);
expect
(
tester
.
widget
<
OutlinedButton
>(
outlinedButton
).
enabled
,
false
);
});
});
testWidgets
(
"OutlinedButton response doesn't hover when disabled"
,
(
WidgetTester
tester
)
async
{
FocusManager
.
instance
.
highlightStrategy
=
FocusHighlightStrategy
.
alwaysTouch
;
final
FocusNode
focusNode
=
FocusNode
(
debugLabel:
'OutlinedButton Focus'
);
final
GlobalKey
childKey
=
GlobalKey
();
bool
hovering
=
false
;
await
tester
.
pumpWidget
(
Material
(
child:
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
SizedBox
(
width:
100
,
height:
100
,
child:
OutlinedButton
(
autofocus:
true
,
onPressed:
()
{},
onLongPress:
()
{},
onHover:
(
bool
value
)
{
hovering
=
value
;
},
focusNode:
focusNode
,
child:
SizedBox
(
key:
childKey
),
),
),
),
),
);
await
tester
.
pumpAndSettle
();
expect
(
focusNode
.
hasPrimaryFocus
,
isTrue
);
final
TestGesture
gesture
=
await
tester
.
createGesture
(
kind:
PointerDeviceKind
.
mouse
);
await
gesture
.
addPointer
();
addTearDown
(
gesture
.
removePointer
);
await
gesture
.
moveTo
(
tester
.
getCenter
(
find
.
byKey
(
childKey
)));
await
tester
.
pumpAndSettle
();
expect
(
hovering
,
isTrue
);
await
tester
.
pumpWidget
(
Material
(
child:
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
SizedBox
(
width:
100
,
height:
100
,
child:
OutlinedButton
(
focusNode:
focusNode
,
onHover:
(
bool
value
)
{
hovering
=
value
;
},
onPressed:
null
,
child:
SizedBox
(
key:
childKey
),
),
),
),
),
);
await
tester
.
pumpAndSettle
();
expect
(
focusNode
.
hasPrimaryFocus
,
isFalse
);
});
testWidgets
(
'disabled and hovered OutlinedButton responds to mouse-exit'
,
(
WidgetTester
tester
)
async
{
int
onHoverCount
=
0
;
late
bool
hover
;
Widget
buildFrame
({
required
bool
enabled
})
{
return
Material
(
child:
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
Center
(
child:
SizedBox
(
width:
100
,
height:
100
,
child:
OutlinedButton
(
onPressed:
enabled
?
()
{
}
:
null
,
onHover:
(
bool
value
)
{
onHoverCount
+=
1
;
hover
=
value
;
},
child:
const
Text
(
'OutlinedButton'
),
),
),
),
),
);
}
await
tester
.
pumpWidget
(
buildFrame
(
enabled:
true
));
final
TestGesture
gesture
=
await
tester
.
createGesture
(
kind:
PointerDeviceKind
.
mouse
);
await
gesture
.
addPointer
();
addTearDown
(
gesture
.
removePointer
);
await
gesture
.
moveTo
(
tester
.
getCenter
(
find
.
byType
(
OutlinedButton
)));
await
tester
.
pumpAndSettle
();
expect
(
onHoverCount
,
1
);
expect
(
hover
,
true
);
await
tester
.
pumpWidget
(
buildFrame
(
enabled:
false
));
await
tester
.
pumpAndSettle
();
await
gesture
.
moveTo
(
Offset
.
zero
);
// Even though the OutlinedButton has been disabled, the mouse-exit still
// causes onHover(false) to be called.
expect
(
onHoverCount
,
2
);
expect
(
hover
,
false
);
await
gesture
.
moveTo
(
tester
.
getCenter
(
find
.
byType
(
OutlinedButton
)));
await
tester
.
pumpAndSettle
();
// We no longer see hover events because the OutlinedButton is disabled
// and it's no longer in the "hovering" state.
expect
(
onHoverCount
,
2
);
expect
(
hover
,
false
);
await
tester
.
pumpWidget
(
buildFrame
(
enabled:
true
));
await
tester
.
pumpAndSettle
();
// The OutlinedButton was enabled while it contained the mouse, however
// we do not call onHover() because it may call setState().
expect
(
onHoverCount
,
2
);
expect
(
hover
,
false
);
await
gesture
.
moveTo
(
tester
.
getCenter
(
find
.
byType
(
OutlinedButton
))
-
const
Offset
(
1
,
1
));
await
tester
.
pumpAndSettle
();
// Moving the mouse a little within the OutlinedButton doesn't change anything.
expect
(
onHoverCount
,
2
);
expect
(
hover
,
false
);
});
testWidgets
(
'Can set OutlinedButton focus and Can set unFocus.'
,
(
WidgetTester
tester
)
async
{
final
FocusNode
node
=
FocusNode
(
debugLabel:
'OutlinedButton Focus'
);
bool
gotFocus
=
false
;
await
tester
.
pumpWidget
(
Material
(
child:
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
OutlinedButton
(
focusNode:
node
,
onFocusChange:
(
bool
focused
)
=>
gotFocus
=
focused
,
onPressed:
()
{
},
child:
const
SizedBox
(),
),
),
),
);
node
.
requestFocus
();
await
tester
.
pump
();
expect
(
gotFocus
,
isTrue
);
expect
(
node
.
hasFocus
,
isTrue
);
node
.
unfocus
();
await
tester
.
pump
();
expect
(
gotFocus
,
isFalse
);
expect
(
node
.
hasFocus
,
isFalse
);
});
testWidgets
(
'When OutlinedButton disable, Can not set OutlinedButton focus.'
,
(
WidgetTester
tester
)
async
{
final
FocusNode
node
=
FocusNode
(
debugLabel:
'OutlinedButton Focus'
);
bool
gotFocus
=
false
;
await
tester
.
pumpWidget
(
Material
(
child:
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
OutlinedButton
(
focusNode:
node
,
onFocusChange:
(
bool
focused
)
=>
gotFocus
=
focused
,
onPressed:
null
,
child:
const
SizedBox
(),
),
),
),
);
node
.
requestFocus
();
await
tester
.
pump
();
expect
(
gotFocus
,
isFalse
);
expect
(
node
.
hasFocus
,
isFalse
);
});
testWidgets
(
"Outline button doesn't crash if disabled during a gesture"
,
(
WidgetTester
tester
)
async
{
testWidgets
(
"Outline button doesn't crash if disabled during a gesture"
,
(
WidgetTester
tester
)
async
{
Widget
buildFrame
(
VoidCallback
?
onPressed
)
{
Widget
buildFrame
(
VoidCallback
?
onPressed
)
{
return
Directionality
(
return
Directionality
(
...
...
packages/flutter/test/material/text_button_test.dart
View file @
d2c8b623
...
@@ -697,6 +697,182 @@ void main() {
...
@@ -697,6 +697,182 @@ void main() {
expect
(
didLongPressButton
,
isTrue
);
expect
(
didLongPressButton
,
isTrue
);
});
});
testWidgets
(
"TextButton response doesn't hover when disabled"
,
(
WidgetTester
tester
)
async
{
FocusManager
.
instance
.
highlightStrategy
=
FocusHighlightStrategy
.
alwaysTouch
;
final
FocusNode
focusNode
=
FocusNode
(
debugLabel:
'TextButton Focus'
);
final
GlobalKey
childKey
=
GlobalKey
();
bool
hovering
=
false
;
await
tester
.
pumpWidget
(
Material
(
child:
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
SizedBox
(
width:
100
,
height:
100
,
child:
TextButton
(
autofocus:
true
,
onPressed:
()
{},
onLongPress:
()
{},
onHover:
(
bool
value
)
{
hovering
=
value
;
},
focusNode:
focusNode
,
child:
SizedBox
(
key:
childKey
),
),
),
),
),
);
await
tester
.
pumpAndSettle
();
expect
(
focusNode
.
hasPrimaryFocus
,
isTrue
);
final
TestGesture
gesture
=
await
tester
.
createGesture
(
kind:
PointerDeviceKind
.
mouse
);
await
gesture
.
addPointer
();
addTearDown
(
gesture
.
removePointer
);
await
gesture
.
moveTo
(
tester
.
getCenter
(
find
.
byKey
(
childKey
)));
await
tester
.
pumpAndSettle
();
expect
(
hovering
,
isTrue
);
await
tester
.
pumpWidget
(
Material
(
child:
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
SizedBox
(
width:
100
,
height:
100
,
child:
TextButton
(
focusNode:
focusNode
,
onHover:
(
bool
value
)
{
hovering
=
value
;
},
onPressed:
null
,
child:
SizedBox
(
key:
childKey
),
),
),
),
),
);
await
tester
.
pumpAndSettle
();
expect
(
focusNode
.
hasPrimaryFocus
,
isFalse
);
});
testWidgets
(
'disabled and hovered TextButton responds to mouse-exit'
,
(
WidgetTester
tester
)
async
{
int
onHoverCount
=
0
;
late
bool
hover
;
Widget
buildFrame
({
required
bool
enabled
})
{
return
Material
(
child:
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
Center
(
child:
SizedBox
(
width:
100
,
height:
100
,
child:
TextButton
(
onPressed:
enabled
?
()
{
}
:
null
,
onHover:
(
bool
value
)
{
onHoverCount
+=
1
;
hover
=
value
;
},
child:
const
Text
(
'TextButton'
),
),
),
),
),
);
}
await
tester
.
pumpWidget
(
buildFrame
(
enabled:
true
));
final
TestGesture
gesture
=
await
tester
.
createGesture
(
kind:
PointerDeviceKind
.
mouse
);
await
gesture
.
addPointer
();
addTearDown
(
gesture
.
removePointer
);
await
gesture
.
moveTo
(
tester
.
getCenter
(
find
.
byType
(
TextButton
)));
await
tester
.
pumpAndSettle
();
expect
(
onHoverCount
,
1
);
expect
(
hover
,
true
);
await
tester
.
pumpWidget
(
buildFrame
(
enabled:
false
));
await
tester
.
pumpAndSettle
();
await
gesture
.
moveTo
(
Offset
.
zero
);
// Even though the TextButton has been disabled, the mouse-exit still
// causes onHover(false) to be called.
expect
(
onHoverCount
,
2
);
expect
(
hover
,
false
);
await
gesture
.
moveTo
(
tester
.
getCenter
(
find
.
byType
(
TextButton
)));
await
tester
.
pumpAndSettle
();
// We no longer see hover events because the TextButton is disabled
// and it's no longer in the "hovering" state.
expect
(
onHoverCount
,
2
);
expect
(
hover
,
false
);
await
tester
.
pumpWidget
(
buildFrame
(
enabled:
true
));
await
tester
.
pumpAndSettle
();
// The TextButton was enabled while it contained the mouse, however
// we do not call onHover() because it may call setState().
expect
(
onHoverCount
,
2
);
expect
(
hover
,
false
);
await
gesture
.
moveTo
(
tester
.
getCenter
(
find
.
byType
(
TextButton
))
-
const
Offset
(
1
,
1
));
await
tester
.
pumpAndSettle
();
// Moving the mouse a little within the TextButton doesn't change anything.
expect
(
onHoverCount
,
2
);
expect
(
hover
,
false
);
});
testWidgets
(
'Can set TextButton focus and Can set unFocus.'
,
(
WidgetTester
tester
)
async
{
final
FocusNode
node
=
FocusNode
(
debugLabel:
'TextButton Focus'
);
bool
gotFocus
=
false
;
await
tester
.
pumpWidget
(
Material
(
child:
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
TextButton
(
focusNode:
node
,
onFocusChange:
(
bool
focused
)
=>
gotFocus
=
focused
,
onPressed:
()
{
},
child:
const
SizedBox
(),
),
),
),
);
node
.
requestFocus
();
await
tester
.
pump
();
expect
(
gotFocus
,
isTrue
);
expect
(
node
.
hasFocus
,
isTrue
);
node
.
unfocus
();
await
tester
.
pump
();
expect
(
gotFocus
,
isFalse
);
expect
(
node
.
hasFocus
,
isFalse
);
});
testWidgets
(
'When TextButton disable, Can not set TextButton focus.'
,
(
WidgetTester
tester
)
async
{
final
FocusNode
node
=
FocusNode
(
debugLabel:
'TextButton Focus'
);
bool
gotFocus
=
false
;
await
tester
.
pumpWidget
(
Material
(
child:
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
TextButton
(
focusNode:
node
,
onFocusChange:
(
bool
focused
)
=>
gotFocus
=
focused
,
onPressed:
null
,
child:
const
SizedBox
(),
),
),
),
);
node
.
requestFocus
();
await
tester
.
pump
();
expect
(
gotFocus
,
isFalse
);
expect
(
node
.
hasFocus
,
isFalse
);
});
testWidgets
(
'TextButton responds to density changes.'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'TextButton responds to density changes.'
,
(
WidgetTester
tester
)
async
{
const
Key
key
=
Key
(
'test'
);
const
Key
key
=
Key
(
'test'
);
const
Key
childKey
=
Key
(
'test child'
);
const
Key
childKey
=
Key
(
'test child'
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment