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
180566f2
Unverified
Commit
180566f2
authored
May 27, 2022
by
Hans Muller
Committed by
GitHub
May 27, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added MaterialStatesController, updated InkWell et al. (#103167)
parent
df52b510
Changes
13
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
852 additions
and
106 deletions
+852
-106
text_button.1.dart
examples/api/lib/material/text_button/text_button.1.dart
+102
-0
text_button.1_test.dart
...les/api/test/material/text_button/text_button.1_test.dart
+51
-0
button_style_button.dart
packages/flutter/lib/src/material/button_style_button.dart
+68
-44
elevated_button.dart
packages/flutter/lib/src/material/elevated_button.dart
+1
-0
ink_well.dart
packages/flutter/lib/src/material/ink_well.dart
+119
-61
material_state.dart
packages/flutter/lib/src/material/material_state.dart
+23
-0
outlined_button.dart
packages/flutter/lib/src/material/outlined_button.dart
+1
-0
text_button.dart
packages/flutter/lib/src/material/text_button.dart
+8
-0
elevated_button_test.dart
packages/flutter/test/material/elevated_button_test.dart
+117
-0
ink_well_test.dart
packages/flutter/test/material/ink_well_test.dart
+43
-0
material_states_controller_test.dart
...lutter/test/material/material_states_controller_test.dart
+85
-0
outlined_button_test.dart
packages/flutter/test/material/outlined_button_test.dart
+117
-0
text_button_test.dart
packages/flutter/test/material/text_button_test.dart
+117
-1
No files found.
examples/api/lib/material/text_button/text_button.1.dart
0 → 100644
View file @
180566f2
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/material.dart'
;
void
main
(
)
{
runApp
(
const
MaterialApp
(
home:
Home
()));
}
class
SelectableButton
extends
StatefulWidget
{
const
SelectableButton
({
super
.
key
,
required
this
.
selected
,
this
.
style
,
required
this
.
onPressed
,
required
this
.
child
,
});
final
bool
selected
;
final
ButtonStyle
?
style
;
final
VoidCallback
?
onPressed
;
final
Widget
child
;
@override
State
<
SelectableButton
>
createState
()
=>
_SelectableButtonState
();
}
class
_SelectableButtonState
extends
State
<
SelectableButton
>
{
late
final
MaterialStatesController
statesController
;
@override
void
initState
()
{
super
.
initState
();
statesController
=
MaterialStatesController
(<
MaterialState
>{
if
(
widget
.
selected
)
MaterialState
.
selected
});
}
@override
void
didUpdateWidget
(
SelectableButton
oldWidget
)
{
super
.
didUpdateWidget
(
oldWidget
);
if
(
widget
.
selected
!=
oldWidget
.
selected
)
{
statesController
.
update
(
MaterialState
.
selected
,
widget
.
selected
);
}
}
@override
Widget
build
(
BuildContext
context
)
{
return
TextButton
(
statesController:
statesController
,
style:
widget
.
style
,
onPressed:
widget
.
onPressed
,
child:
widget
.
child
,
);
}
}
class
Home
extends
StatefulWidget
{
const
Home
({
super
.
key
});
@override
State
<
Home
>
createState
()
=>
_HomeState
();
}
class
_HomeState
extends
State
<
Home
>
{
bool
selected
=
false
;
@override
Widget
build
(
BuildContext
context
)
{
return
Scaffold
(
body:
Center
(
child:
SelectableButton
(
selected:
selected
,
style:
ButtonStyle
(
foregroundColor:
MaterialStateProperty
.
resolveWith
<
Color
?>(
(
Set
<
MaterialState
>
states
)
{
if
(
states
.
contains
(
MaterialState
.
selected
))
{
return
Colors
.
white
;
}
return
null
;
// defer to the defaults
},
),
backgroundColor:
MaterialStateProperty
.
resolveWith
<
Color
?>(
(
Set
<
MaterialState
>
states
)
{
if
(
states
.
contains
(
MaterialState
.
selected
))
{
return
Colors
.
indigo
;
}
return
null
;
// defer to the defaults
},
),
),
onPressed:
()
{
setState
(()
{
selected
=
!
selected
;
});
},
child:
const
Text
(
'toggle selected'
),
),
),
);
}
}
examples/api/test/material/text_button/text_button.1_test.dart
0 → 100644
View file @
180566f2
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/material.dart'
;
import
'package:flutter_api_samples/material/text_button/text_button.1.dart'
as
example
;
import
'package:flutter_test/flutter_test.dart'
;
void
main
(
)
{
testWidgets
(
'SelectableButton'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
ThemeData
(
colorScheme:
const
ColorScheme
.
light
(),
),
home:
const
example
.
Home
(),
),
);
final
Finder
button
=
find
.
byType
(
example
.
SelectableButton
);
example
.
SelectableButton
buttonWidget
()
=>
tester
.
widget
<
example
.
SelectableButton
>(
button
);
Material
buttonMaterial
()
{
return
tester
.
widget
<
Material
>(
find
.
descendant
(
of:
find
.
byType
(
example
.
SelectableButton
),
matching:
find
.
byType
(
Material
),
),
);
}
expect
(
buttonWidget
().
selected
,
false
);
expect
(
buttonMaterial
().
textStyle
!.
color
,
const
ColorScheme
.
light
().
primary
);
// default button foreground color
expect
(
buttonMaterial
().
color
,
Colors
.
transparent
);
// default button background color
await
tester
.
tap
(
button
);
// Toggles the button's selected property.
await
tester
.
pumpAndSettle
();
expect
(
buttonWidget
().
selected
,
true
);
expect
(
buttonMaterial
().
textStyle
!.
color
,
Colors
.
white
);
expect
(
buttonMaterial
().
color
,
Colors
.
indigo
);
await
tester
.
tap
(
button
);
// Toggles the button's selected property.
await
tester
.
pumpAndSettle
();
expect
(
buttonWidget
().
selected
,
false
);
expect
(
buttonMaterial
().
textStyle
!.
color
,
const
ColorScheme
.
light
().
primary
);
expect
(
buttonMaterial
().
color
,
Colors
.
transparent
);
});
}
packages/flutter/lib/src/material/button_style_button.dart
View file @
180566f2
...
...
@@ -14,7 +14,6 @@ import 'constants.dart';
import
'ink_well.dart'
;
import
'material.dart'
;
import
'material_state.dart'
;
import
'material_state_mixin.dart'
;
import
'theme_data.dart'
;
/// The base [StatefulWidget] class for buttons whose style is defined by a [ButtonStyle] object.
...
...
@@ -39,6 +38,7 @@ abstract class ButtonStyleButton extends StatefulWidget {
required
this
.
focusNode
,
required
this
.
autofocus
,
required
this
.
clipBehavior
,
this
.
statesController
,
required
this
.
child
,
})
:
assert
(
autofocus
!=
null
),
assert
(
clipBehavior
!=
null
);
...
...
@@ -95,6 +95,9 @@ abstract class ButtonStyleButton extends StatefulWidget {
/// {@macro flutter.widgets.Focus.autofocus}
final
bool
autofocus
;
/// {@macro flutter.material.inkwell.statesController}
final
MaterialStatesController
?
statesController
;
/// Typically the button's label.
final
Widget
?
child
;
...
...
@@ -191,36 +194,61 @@ abstract class ButtonStyleButton extends StatefulWidget {
/// * [TextButton], a simple button without a shadow.
/// * [ElevatedButton], a filled button whose material elevates when pressed.
/// * [OutlinedButton], similar to [TextButton], but with an outline.
class
_ButtonStyleState
extends
State
<
ButtonStyleButton
>
with
MaterialStateMixin
,
TickerProviderStateMixin
{
AnimationController
?
_controller
;
double
?
_elevation
;
Color
?
_backgroundColor
;
class
_ButtonStyleState
extends
State
<
ButtonStyleButton
>
with
TickerProviderStateMixin
{
AnimationController
?
controller
;
double
?
elevation
;
Color
?
backgroundColor
;
MaterialStatesController
?
internalStatesController
;
void
handleStatesControllerChange
()
{
// Force a rebuild to resolve MaterialStateProperty properties
setState
(()
{
});
}
@override
void
initState
()
{
super
.
initState
();
setMaterialState
(
MaterialState
.
disabled
,
!
widget
.
enabled
);
MaterialStatesController
get
statesController
=>
widget
.
statesController
??
internalStatesController
!;
void
initStatesController
()
{
if
(
widget
.
statesController
==
null
)
{
internalStatesController
=
MaterialStatesController
();
}
statesController
.
update
(
MaterialState
.
disabled
,
!
widget
.
enabled
);
statesController
.
addListener
(
handleStatesControllerChange
);
}
@override
void
dispos
e
()
{
_controller
?.
dispos
e
();
super
.
dispose
();
void
initStat
e
()
{
super
.
initStat
e
();
initStatesController
();
}
@override
void
didUpdateWidget
(
ButtonStyleButton
oldWidget
)
{
super
.
didUpdateWidget
(
oldWidget
);
setMaterialState
(
MaterialState
.
disabled
,
!
widget
.
enabled
);
// If the button is disabled while a press gesture is currently ongoing,
// InkWell makes a call to handleHighlightChanged. This causes an exception
// because it calls setState in the middle of a build. To preempt this, we
// manually update pressed to false when this situation occurs.
if
(
isDisabled
&&
isPressed
)
{
removeMaterialState
(
MaterialState
.
pressed
);
if
(
widget
.
statesController
!=
oldWidget
.
statesController
)
{
oldWidget
.
statesController
?.
removeListener
(
handleStatesControllerChange
);
if
(
widget
.
statesController
!=
null
)
{
internalStatesController
?.
dispose
();
internalStatesController
=
null
;
}
initStatesController
();
}
if
(
widget
.
enabled
!=
oldWidget
.
enabled
)
{
statesController
.
update
(
MaterialState
.
disabled
,
!
widget
.
enabled
);
if
(!
widget
.
enabled
)
{
// The button may have been disabled while a press gesture is currently underway.
statesController
.
update
(
MaterialState
.
pressed
,
false
);
}
}
}
@override
void
dispose
()
{
statesController
.
removeListener
(
handleStatesControllerChange
);
internalStatesController
?.
dispose
();
controller
?.
dispose
();
super
.
dispose
();
}
@override
Widget
build
(
BuildContext
context
)
{
final
ButtonStyle
?
widgetStyle
=
widget
.
style
;
...
...
@@ -237,7 +265,9 @@ class _ButtonStyleState extends State<ButtonStyleButton> with MaterialStateMixin
T
?
resolve
<
T
>(
MaterialStateProperty
<
T
>?
Function
(
ButtonStyle
?
style
)
getProperty
)
{
return
effectiveValue
(
(
ButtonStyle
?
style
)
=>
getProperty
(
style
)?.
resolve
(
materialStates
),
(
ButtonStyle
?
style
)
{
return
getProperty
(
style
)?.
resolve
(
statesController
.
value
);
},
);
}
...
...
@@ -254,7 +284,7 @@ class _ButtonStyleState extends State<ButtonStyleButton> with MaterialStateMixin
final
BorderSide
?
resolvedSide
=
resolve
<
BorderSide
?>((
ButtonStyle
?
style
)
=>
style
?.
side
);
final
OutlinedBorder
?
resolvedShape
=
resolve
<
OutlinedBorder
?>((
ButtonStyle
?
style
)
=>
style
?.
shape
);
final
MaterialStateMouseCursor
resolvedM
ouseCursor
=
_MouseCursor
(
final
MaterialStateMouseCursor
m
ouseCursor
=
_MouseCursor
(
(
Set
<
MaterialState
>
states
)
=>
effectiveValue
((
ButtonStyle
?
style
)
=>
style
?.
mouseCursor
?.
resolve
(
states
)),
);
...
...
@@ -309,16 +339,16 @@ class _ButtonStyleState extends State<ButtonStyleButton> with MaterialStateMixin
// animates its elevation but not its color. SKIA renders non-zero
// elevations as a shadow colored fill behind the Material's background.
if
(
resolvedAnimationDuration
!
>
Duration
.
zero
&&
_
elevation
!=
null
&&
_
backgroundColor
!=
null
&&
_
elevation
!=
resolvedElevation
&&
_
backgroundColor
!.
value
!=
resolvedBackgroundColor
!.
value
&&
_
backgroundColor
!.
opacity
==
1
&&
elevation
!=
null
&&
backgroundColor
!=
null
&&
elevation
!=
resolvedElevation
&&
backgroundColor
!.
value
!=
resolvedBackgroundColor
!.
value
&&
backgroundColor
!.
opacity
==
1
&&
resolvedBackgroundColor
.
opacity
<
1
&&
resolvedElevation
==
0
)
{
if
(
_
controller
?.
duration
!=
resolvedAnimationDuration
)
{
_
controller
?.
dispose
();
_
controller
=
AnimationController
(
if
(
controller
?.
duration
!=
resolvedAnimationDuration
)
{
controller
?.
dispose
();
controller
=
AnimationController
(
duration:
resolvedAnimationDuration
,
vsync:
this
,
)
...
...
@@ -328,12 +358,12 @@ class _ButtonStyleState extends State<ButtonStyleButton> with MaterialStateMixin
}
});
}
resolvedBackgroundColor
=
_
backgroundColor
;
// Defer changing the background color.
_
controller
!.
value
=
0
;
_
controller
!.
forward
();
resolvedBackgroundColor
=
backgroundColor
;
// Defer changing the background color.
controller
!.
value
=
0
;
controller
!.
forward
();
}
_
elevation
=
resolvedElevation
;
_
backgroundColor
=
resolvedBackgroundColor
;
elevation
=
resolvedElevation
;
backgroundColor
=
resolvedBackgroundColor
;
final
Widget
result
=
ConstrainedBox
(
constraints:
effectiveConstraints
,
...
...
@@ -350,24 +380,18 @@ class _ButtonStyleState extends State<ButtonStyleButton> with MaterialStateMixin
child:
InkWell
(
onTap:
widget
.
onPressed
,
onLongPress:
widget
.
onLongPress
,
onHighlightChanged:
updateMaterialState
(
MaterialState
.
pressed
),
onHover:
updateMaterialState
(
MaterialState
.
hovered
,
onChanged:
widget
.
onHover
,
),
mouseCursor:
resolvedMouseCursor
,
onHover:
widget
.
onHover
,
mouseCursor:
mouseCursor
,
enableFeedback:
resolvedEnableFeedback
,
focusNode:
widget
.
focusNode
,
canRequestFocus:
widget
.
enabled
,
onFocusChange:
updateMaterialState
(
MaterialState
.
focused
,
onChanged:
widget
.
onFocusChange
,
),
onFocusChange:
widget
.
onFocusChange
,
autofocus:
widget
.
autofocus
,
splashFactory:
resolvedSplashFactory
,
overlayColor:
overlayColor
,
highlightColor:
Colors
.
transparent
,
customBorder:
resolvedShape
,
statesController:
statesController
,
child:
IconTheme
.
merge
(
data:
IconThemeData
(
color:
resolvedForegroundColor
),
child:
Padding
(
...
...
packages/flutter/lib/src/material/elevated_button.dart
View file @
180566f2
...
...
@@ -71,6 +71,7 @@ class ElevatedButton extends ButtonStyleButton {
super
.
focusNode
,
super
.
autofocus
=
false
,
super
.
clipBehavior
=
Clip
.
none
,
super
.
statesController
,
required
super
.
child
,
});
...
...
packages/flutter/lib/src/material/ink_well.dart
View file @
180566f2
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/material/material_state.dart
View file @
180566f2
...
...
@@ -686,3 +686,26 @@ class MaterialStatePropertyAll<T> implements MaterialStateProperty<T> {
@override
String
toString
()
=>
'MaterialStatePropertyAll(
$value
)'
;
}
/// Manages a set of [MaterialState]s and notifies listeners of changes.
///
/// Used by widgets that expose their internal state for the sake of
/// extensions that add support for additional states. See
/// [TextButton.statesController] for example.
///
/// The controller's [value] is its current set of states. Listeners
/// are notified whenever the [value] changes. The [value] should only be
/// changed with [update]; it should not be modified directly.
class
MaterialStatesController
extends
ValueNotifier
<
Set
<
MaterialState
>>
{
/// Creates a MaterialStatesController.
MaterialStatesController
([
Set
<
MaterialState
>?
value
])
:
super
(<
MaterialState
>{...?
value
});
/// Adds [state] to [value] if [add] is true, and removes it otherwise,
/// and notifies listeners if [value] has changed.
void
update
(
MaterialState
state
,
bool
add
)
{
final
bool
valueChanged
=
add
?
value
.
add
(
state
)
:
value
.
remove
(
state
);
if
(
valueChanged
)
{
notifyListeners
();
}
}
}
packages/flutter/lib/src/material/outlined_button.dart
View file @
180566f2
...
...
@@ -76,6 +76,7 @@ class OutlinedButton extends ButtonStyleButton {
super
.
focusNode
,
super
.
autofocus
=
false
,
super
.
clipBehavior
=
Clip
.
none
,
super
.
statesController
,
required
Widget
super
.
child
,
});
...
...
packages/flutter/lib/src/material/text_button.dart
View file @
180566f2
...
...
@@ -57,6 +57,13 @@ import 'theme_data.dart';
/// ** See code in examples/api/lib/material/text_button/text_button.0.dart **
/// {@end-tool}
///
/// {@tool dartpad}
/// This sample demonstrates using the [statesController] parameter to create a button
/// that adds support for [MaterialState.selected].
///
/// ** See code in examples/api/lib/material/text_button/text_button.1.dart **
/// {@end-tool}
///
/// See also:
///
/// * [OutlinedButton], a [TextButton] with a border outline.
...
...
@@ -76,6 +83,7 @@ class TextButton extends ButtonStyleButton {
super
.
focusNode
,
super
.
autofocus
=
false
,
super
.
clipBehavior
=
Clip
.
none
,
super
.
statesController
,
required
Widget
super
.
child
,
});
...
...
packages/flutter/test/material/elevated_button_test.dart
View file @
180566f2
...
...
@@ -1554,6 +1554,123 @@ void main() {
expect
(
RendererBinding
.
instance
.
mouseTracker
.
debugDeviceActiveCursor
(
1
),
SystemMouseCursors
.
basic
);
});
testWidgets
(
'ElevatedButton statesController'
,
(
WidgetTester
tester
)
async
{
int
count
=
0
;
void
valueChanged
()
{
count
+=
1
;
}
final
MaterialStatesController
controller
=
MaterialStatesController
();
controller
.
addListener
(
valueChanged
);
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Center
(
child:
ElevatedButton
(
statesController:
controller
,
onPressed:
()
{
},
child:
const
Text
(
'button'
),
),
),
),
);
expect
(
controller
.
value
,
<
MaterialState
>{});
expect
(
count
,
0
);
final
Offset
center
=
tester
.
getCenter
(
find
.
byType
(
ElevatedButton
));
final
TestGesture
gesture
=
await
tester
.
createGesture
(
kind:
PointerDeviceKind
.
mouse
,
);
await
gesture
.
addPointer
();
await
gesture
.
moveTo
(
center
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
});
expect
(
count
,
1
);
await
gesture
.
moveTo
(
Offset
.
zero
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{});
expect
(
count
,
2
);
await
gesture
.
moveTo
(
center
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
});
expect
(
count
,
3
);
await
gesture
.
down
(
center
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
,
MaterialState
.
pressed
});
expect
(
count
,
4
);
await
gesture
.
up
();
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
});
expect
(
count
,
5
);
await
gesture
.
moveTo
(
Offset
.
zero
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{});
expect
(
count
,
6
);
await
gesture
.
down
(
center
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
,
MaterialState
.
pressed
});
expect
(
count
,
8
);
// adds hovered and pressed - two changes
// If the button is rebuilt disabled, then the pressed state is
// removed.
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Center
(
child:
ElevatedButton
(
statesController:
controller
,
onPressed:
null
,
child:
const
Text
(
'button'
),
),
),
),
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
,
MaterialState
.
disabled
});
expect
(
count
,
10
);
// removes pressed and adds disabled - two changes
await
gesture
.
moveTo
(
Offset
.
zero
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
disabled
});
expect
(
count
,
11
);
await
gesture
.
removePointer
();
});
testWidgets
(
'Disabled ElevatedButton statesController'
,
(
WidgetTester
tester
)
async
{
int
count
=
0
;
void
valueChanged
()
{
count
+=
1
;
}
final
MaterialStatesController
controller
=
MaterialStatesController
();
controller
.
addListener
(
valueChanged
);
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Center
(
child:
ElevatedButton
(
statesController:
controller
,
onPressed:
null
,
child:
const
Text
(
'button'
),
),
),
),
);
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
disabled
});
expect
(
count
,
1
);
});
}
TextStyle
_iconStyle
(
WidgetTester
tester
,
IconData
icon
)
{
...
...
packages/flutter/test/material/ink_well_test.dart
View file @
180566f2
...
...
@@ -1513,4 +1513,47 @@ void main() {
final
RenderObject
inkFeatures
=
tester
.
allRenderObjects
.
firstWhere
((
RenderObject
object
)
=>
object
.
runtimeType
.
toString
()
==
'_RenderInkFeatures'
);
expect
(
inkFeatures
,
paintsExactlyCountTimes
(
#drawCircle
,
0
));
});
testWidgets
(
'InkWell dispose statesController'
,
(
WidgetTester
tester
)
async
{
int
tapCount
=
0
;
Widget
buildFrame
(
MaterialStatesController
?
statesController
)
{
return
MaterialApp
(
home:
Scaffold
(
body:
Center
(
child:
InkWell
(
statesController:
statesController
,
onTap:
()
{
tapCount
+=
1
;
},
child:
const
Text
(
'inkwell'
),
),
),
),
);
}
final
MaterialStatesController
controller
=
MaterialStatesController
();
int
pressedCount
=
0
;
controller
.
addListener
(()
{
if
(
controller
.
value
.
contains
(
MaterialState
.
pressed
))
{
pressedCount
+=
1
;
}
});
await
tester
.
pumpWidget
(
buildFrame
(
controller
));
await
tester
.
tap
(
find
.
byType
(
InkWell
));
await
tester
.
pumpAndSettle
();
expect
(
tapCount
,
1
);
expect
(
pressedCount
,
1
);
await
tester
.
pumpWidget
(
buildFrame
(
null
));
await
tester
.
tap
(
find
.
byType
(
InkWell
));
await
tester
.
pumpAndSettle
();
expect
(
tapCount
,
2
);
expect
(
pressedCount
,
1
);
await
tester
.
pumpWidget
(
buildFrame
(
controller
));
await
tester
.
tap
(
find
.
byType
(
InkWell
));
await
tester
.
pumpAndSettle
();
expect
(
tapCount
,
3
);
expect
(
pressedCount
,
2
);
});
}
packages/flutter/test/material/material_states_controller_test.dart
0 → 100644
View file @
180566f2
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/material.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
void
main
(
)
{
test
(
'MaterialStatesController constructor'
,
()
{
expect
(
MaterialStatesController
().
value
,
<
MaterialState
>{});
expect
(
MaterialStatesController
(<
MaterialState
>{}).
value
,
<
MaterialState
>{});
expect
(
MaterialStatesController
(<
MaterialState
>{
MaterialState
.
selected
}).
value
,
<
MaterialState
>{
MaterialState
.
selected
});
});
test
(
'MaterialStatesController update, listener'
,
()
{
int
count
=
0
;
void
valueChanged
()
{
count
+=
1
;
}
final
MaterialStatesController
controller
=
MaterialStatesController
();
controller
.
addListener
(
valueChanged
);
controller
.
update
(
MaterialState
.
selected
,
true
);
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
selected
});
expect
(
count
,
1
);
controller
.
update
(
MaterialState
.
selected
,
true
);
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
selected
});
expect
(
count
,
1
);
controller
.
update
(
MaterialState
.
hovered
,
false
);
expect
(
count
,
1
);
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
selected
});
controller
.
update
(
MaterialState
.
selected
,
false
);
expect
(
count
,
2
);
expect
(
controller
.
value
,
<
MaterialState
>{});
controller
.
update
(
MaterialState
.
hovered
,
true
);
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
});
expect
(
count
,
3
);
controller
.
update
(
MaterialState
.
hovered
,
true
);
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
});
expect
(
count
,
3
);
controller
.
update
(
MaterialState
.
pressed
,
true
);
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
,
MaterialState
.
pressed
});
expect
(
count
,
4
);
controller
.
update
(
MaterialState
.
selected
,
true
);
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
,
MaterialState
.
pressed
,
MaterialState
.
selected
});
expect
(
count
,
5
);
controller
.
update
(
MaterialState
.
selected
,
false
);
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
,
MaterialState
.
pressed
});
expect
(
count
,
6
);
controller
.
update
(
MaterialState
.
selected
,
false
);
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
,
MaterialState
.
pressed
});
expect
(
count
,
6
);
controller
.
update
(
MaterialState
.
pressed
,
false
);
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
});
expect
(
count
,
7
);
controller
.
update
(
MaterialState
.
hovered
,
false
);
expect
(
controller
.
value
,
<
MaterialState
>{});
expect
(
count
,
8
);
controller
.
removeListener
(
valueChanged
);
controller
.
update
(
MaterialState
.
selected
,
true
);
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
selected
});
expect
(
count
,
8
);
});
test
(
'MaterialStatesController const initial value'
,
()
{
int
count
=
0
;
void
valueChanged
()
{
count
+=
1
;
}
final
MaterialStatesController
controller
=
MaterialStatesController
(
const
<
MaterialState
>{
MaterialState
.
selected
});
controller
.
addListener
(
valueChanged
);
controller
.
update
(
MaterialState
.
selected
,
true
);
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
selected
});
expect
(
count
,
0
);
controller
.
update
(
MaterialState
.
selected
,
false
);
expect
(
controller
.
value
,
<
MaterialState
>{});
expect
(
count
,
1
);
});
}
packages/flutter/test/material/outlined_button_test.dart
View file @
180566f2
...
...
@@ -1717,6 +1717,123 @@ void main() {
expect
(
RendererBinding
.
instance
.
mouseTracker
.
debugDeviceActiveCursor
(
1
),
SystemMouseCursors
.
basic
);
});
testWidgets
(
'OutlinedButton statesController'
,
(
WidgetTester
tester
)
async
{
int
count
=
0
;
void
valueChanged
()
{
count
+=
1
;
}
final
MaterialStatesController
controller
=
MaterialStatesController
();
controller
.
addListener
(
valueChanged
);
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Center
(
child:
OutlinedButton
(
statesController:
controller
,
onPressed:
()
{
},
child:
const
Text
(
'button'
),
),
),
),
);
expect
(
controller
.
value
,
<
MaterialState
>{});
expect
(
count
,
0
);
final
Offset
center
=
tester
.
getCenter
(
find
.
byType
(
OutlinedButton
));
final
TestGesture
gesture
=
await
tester
.
createGesture
(
kind:
PointerDeviceKind
.
mouse
,
);
await
gesture
.
addPointer
();
await
gesture
.
moveTo
(
center
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
});
expect
(
count
,
1
);
await
gesture
.
moveTo
(
Offset
.
zero
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{});
expect
(
count
,
2
);
await
gesture
.
moveTo
(
center
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
});
expect
(
count
,
3
);
await
gesture
.
down
(
center
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
,
MaterialState
.
pressed
});
expect
(
count
,
4
);
await
gesture
.
up
();
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
});
expect
(
count
,
5
);
await
gesture
.
moveTo
(
Offset
.
zero
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{});
expect
(
count
,
6
);
await
gesture
.
down
(
center
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
,
MaterialState
.
pressed
});
expect
(
count
,
8
);
// adds hovered and pressed - two changes
// If the button is rebuilt disabled, then the pressed state is
// removed.
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Center
(
child:
OutlinedButton
(
statesController:
controller
,
onPressed:
null
,
child:
const
Text
(
'button'
),
),
),
),
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
,
MaterialState
.
disabled
});
expect
(
count
,
10
);
// removes pressed and adds disabled - two changes
await
gesture
.
moveTo
(
Offset
.
zero
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
disabled
});
expect
(
count
,
11
);
await
gesture
.
removePointer
();
});
testWidgets
(
'Disabled OutlinedButton statesController'
,
(
WidgetTester
tester
)
async
{
int
count
=
0
;
void
valueChanged
()
{
count
+=
1
;
}
final
MaterialStatesController
controller
=
MaterialStatesController
();
controller
.
addListener
(
valueChanged
);
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Center
(
child:
OutlinedButton
(
statesController:
controller
,
onPressed:
null
,
child:
const
Text
(
'button'
),
),
),
),
);
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
disabled
});
expect
(
count
,
1
);
});
}
TextStyle
_iconStyle
(
WidgetTester
tester
,
IconData
icon
)
{
...
...
packages/flutter/test/material/text_button_test.dart
View file @
180566f2
...
...
@@ -441,7 +441,6 @@ void main() {
),
);
final
TestGesture
gesture
=
await
tester
.
createGesture
(
kind:
PointerDeviceKind
.
mouse
);
await
gesture
.
addPointer
();
await
gesture
.
moveTo
(
tester
.
getCenter
(
find
.
byType
(
TextButton
)));
...
...
@@ -1525,6 +1524,123 @@ void main() {
expect
(
RendererBinding
.
instance
.
mouseTracker
.
debugDeviceActiveCursor
(
1
),
SystemMouseCursors
.
basic
);
});
testWidgets
(
'TextButton statesController'
,
(
WidgetTester
tester
)
async
{
int
count
=
0
;
void
valueChanged
()
{
count
+=
1
;
}
final
MaterialStatesController
controller
=
MaterialStatesController
();
controller
.
addListener
(
valueChanged
);
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Center
(
child:
TextButton
(
statesController:
controller
,
onPressed:
()
{
},
child:
const
Text
(
'button'
),
),
),
),
);
expect
(
controller
.
value
,
<
MaterialState
>{});
expect
(
count
,
0
);
final
Offset
center
=
tester
.
getCenter
(
find
.
byType
(
TextButton
));
final
TestGesture
gesture
=
await
tester
.
createGesture
(
kind:
PointerDeviceKind
.
mouse
,
);
await
gesture
.
addPointer
();
await
gesture
.
moveTo
(
center
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
});
expect
(
count
,
1
);
await
gesture
.
moveTo
(
Offset
.
zero
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{});
expect
(
count
,
2
);
await
gesture
.
moveTo
(
center
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
});
expect
(
count
,
3
);
await
gesture
.
down
(
center
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
,
MaterialState
.
pressed
});
expect
(
count
,
4
);
await
gesture
.
up
();
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
});
expect
(
count
,
5
);
await
gesture
.
moveTo
(
Offset
.
zero
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{});
expect
(
count
,
6
);
await
gesture
.
down
(
center
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
,
MaterialState
.
pressed
});
expect
(
count
,
8
);
// adds hovered and pressed - two changes
// If the button is rebuilt disabled, then the pressed state is
// removed.
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Center
(
child:
TextButton
(
statesController:
controller
,
onPressed:
null
,
child:
const
Text
(
'button'
),
),
),
),
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
hovered
,
MaterialState
.
disabled
});
expect
(
count
,
10
);
// removes pressed and adds disabled - two changes
await
gesture
.
moveTo
(
Offset
.
zero
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
disabled
});
expect
(
count
,
11
);
await
gesture
.
removePointer
();
});
testWidgets
(
'Disabled TextButton statesController'
,
(
WidgetTester
tester
)
async
{
int
count
=
0
;
void
valueChanged
()
{
count
+=
1
;
}
final
MaterialStatesController
controller
=
MaterialStatesController
();
controller
.
addListener
(
valueChanged
);
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Center
(
child:
TextButton
(
statesController:
controller
,
onPressed:
null
,
child:
const
Text
(
'button'
),
),
),
),
);
expect
(
controller
.
value
,
<
MaterialState
>{
MaterialState
.
disabled
});
expect
(
count
,
1
);
});
}
TextStyle
?
_iconStyle
(
WidgetTester
tester
,
IconData
icon
)
{
...
...
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