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
24499077
Unverified
Commit
24499077
authored
Nov 14, 2022
by
Qun Cheng
Committed by
GitHub
Nov 14, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed the color curve issue (#115188)
parent
436fb4c6
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
146 additions
and
19 deletions
+146
-19
switch.dart
packages/flutter/lib/src/material/switch.dart
+63
-19
switch_test.dart
packages/flutter/test/material/switch_test.dart
+83
-0
No files found.
packages/flutter/lib/src/material/switch.dart
View file @
24499077
...
...
@@ -620,9 +620,15 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
// During a drag we may have modified the curve, reset it if its possible
// to do without visual discontinuation.
if
(
position
.
value
==
0.0
||
position
.
value
==
1.0
)
{
position
..
curve
=
Curves
.
easeIn
..
reverseCurve
=
Curves
.
easeOut
;
if
(
Theme
.
of
(
context
).
useMaterial3
)
{
position
..
curve
=
Curves
.
easeOutBack
..
reverseCurve
=
Curves
.
easeOutBack
.
flipped
;
}
else
{
position
..
curve
=
Curves
.
easeIn
..
reverseCurve
=
Curves
.
easeOut
;
}
}
animateToValue
();
}
...
...
@@ -693,7 +699,7 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
void
_handleDragEnd
(
DragEndDetails
details
)
{
if
(
position
.
value
>=
0.5
!=
widget
.
value
)
{
widget
.
onChanged
!
(!
widget
.
value
);
widget
.
onChanged
?.
call
(!
widget
.
value
);
// Wait with finishing the animation until widget.value has changed to
// !widget.value as part of the widget.onChanged call above.
setState
(()
{
...
...
@@ -709,7 +715,7 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
void
_handleChanged
(
bool
?
value
)
{
assert
(
value
!=
null
);
assert
(
widget
.
onChanged
!=
null
);
widget
.
onChanged
!
(
value
!);
widget
.
onChanged
?.
call
(
value
!);
}
@override
...
...
@@ -727,11 +733,6 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
final
SwitchThemeData
defaults
=
theme
.
useMaterial3
?
_SwitchDefaultsM3
(
context
)
:
_SwitchDefaultsM2
(
context
);
positionController
.
duration
=
Duration
(
milliseconds:
switchConfig
.
toggleDuration
);
if
(
theme
.
useMaterial3
)
{
position
..
curve
=
Curves
.
easeOutBack
..
reverseCurve
=
Curves
.
easeOutBack
.
flipped
;
}
// Colors need to be resolved in selected and non selected states separately
// so that they can be lerped between.
...
...
@@ -780,12 +781,20 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
??
defaults
.
overlayColor
!.
resolve
(
hoveredStates
)!;
final
Set
<
MaterialState
>
activePressedStates
=
activeStates
..
add
(
MaterialState
.
pressed
);
final
Color
effectiveActivePressedThumbColor
=
widget
.
thumbColor
?.
resolve
(
activePressedStates
)
??
_widgetThumbColor
.
resolve
(
activePressedStates
)
??
switchTheme
.
thumbColor
?.
resolve
(
activePressedStates
)
??
defaults
.
thumbColor
!.
resolve
(
activePressedStates
)!;
final
Color
effectiveActivePressedOverlayColor
=
widget
.
overlayColor
?.
resolve
(
activePressedStates
)
??
switchTheme
.
overlayColor
?.
resolve
(
activePressedStates
)
??
activeThumbColor
?.
withAlpha
(
kRadialReactionAlpha
)
??
defaults
.
overlayColor
!.
resolve
(
activePressedStates
)!;
final
Set
<
MaterialState
>
inactivePressedStates
=
inactiveStates
..
add
(
MaterialState
.
pressed
);
final
Color
effectiveInactivePressedThumbColor
=
widget
.
thumbColor
?.
resolve
(
inactivePressedStates
)
??
_widgetThumbColor
.
resolve
(
inactivePressedStates
)
??
switchTheme
.
thumbColor
?.
resolve
(
inactivePressedStates
)
??
defaults
.
thumbColor
!.
resolve
(
inactivePressedStates
)!;
final
Color
effectiveInactivePressedOverlayColor
=
widget
.
overlayColor
?.
resolve
(
inactivePressedStates
)
??
switchTheme
.
overlayColor
?.
resolve
(
inactivePressedStates
)
??
inactiveThumbColor
?.
withAlpha
(
kRadialReactionAlpha
)
...
...
@@ -830,6 +839,8 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
..
isHovered
=
states
.
contains
(
MaterialState
.
hovered
)
..
activeColor
=
effectiveActiveThumbColor
..
inactiveColor
=
effectiveInactiveThumbColor
..
activePressedColor
=
effectiveActivePressedThumbColor
..
inactivePressedColor
=
effectiveInactivePressedThumbColor
..
activeThumbImage
=
widget
.
activeThumbImage
..
onActiveThumbImageError
=
widget
.
onActiveThumbImageError
..
inactiveThumbImage
=
widget
.
inactiveThumbImage
...
...
@@ -926,6 +937,28 @@ class _SwitchPainter extends ToggleablePainter {
notifyListeners
();
}
Color
get
activePressedColor
=>
_activePressedColor
!;
Color
?
_activePressedColor
;
set
activePressedColor
(
Color
?
value
)
{
assert
(
value
!=
null
);
if
(
value
==
_activePressedColor
)
{
return
;
}
_activePressedColor
=
value
;
notifyListeners
();
}
Color
get
inactivePressedColor
=>
_inactivePressedColor
!;
Color
?
_inactivePressedColor
;
set
inactivePressedColor
(
Color
?
value
)
{
assert
(
value
!=
null
);
if
(
value
==
_inactivePressedColor
)
{
return
;
}
_inactivePressedColor
=
value
;
notifyListeners
();
}
double
get
activeThumbRadius
=>
_activeThumbRadius
!;
double
?
_activeThumbRadius
;
set
activeThumbRadius
(
double
value
)
{
...
...
@@ -1180,7 +1213,7 @@ class _SwitchPainter extends ToggleablePainter {
visualPosition
=
currentValue
;
break
;
}
if
(
reaction
.
status
==
AnimationStatus
.
reverse
&&
_stopPressAnimation
==
false
)
{
if
(
reaction
.
status
==
AnimationStatus
.
reverse
&&
!
_stopPressAnimation
)
{
_stopPressAnimation
=
true
;
}
else
{
_stopPressAnimation
=
false
;
...
...
@@ -1189,7 +1222,7 @@ class _SwitchPainter extends ToggleablePainter {
// To get the thumb radius when the press ends, the value can be any number
// between activeThumbRadius/inactiveThumbRadius and pressedThumbRadius.
if
(!
_stopPressAnimation
)
{
if
(
reaction
.
status
==
AnimationStatus
.
c
ompleted
)
{
if
(
reaction
.
isC
ompleted
)
{
// This happens when the thumb is dragged instead of being tapped.
_pressedInactiveThumbRadius
=
lerpDouble
(
inactiveThumbRadius
,
pressedThumbRadius
,
reaction
.
value
);
_pressedActiveThumbRadius
=
lerpDouble
(
activeThumbRadius
,
pressedThumbRadius
,
reaction
.
value
);
...
...
@@ -1248,10 +1281,10 @@ class _SwitchPainter extends ToggleablePainter {
}
Size
thumbSize
;
if
(
reaction
.
status
==
AnimationStatus
.
c
ompleted
)
{
if
(
reaction
.
isC
ompleted
)
{
thumbSize
=
Size
.
fromRadius
(
pressedThumbRadius
);
}
else
{
if
(
position
.
status
==
AnimationStatus
.
d
ismissed
||
position
.
status
==
AnimationStatus
.
forward
)
{
if
(
position
.
isD
ismissed
||
position
.
status
==
AnimationStatus
.
forward
)
{
thumbSize
=
thumbSizeAnimation
(
true
).
value
;
}
else
{
thumbSize
=
thumbSizeAnimation
(
false
).
value
;
...
...
@@ -1262,10 +1295,21 @@ class _SwitchPainter extends ToggleablePainter {
final
double
inset
=
thumbOffset
==
null
?
0
:
1.0
-
(
currentValue
-
thumbOffset
!).
abs
()
*
2.0
;
thumbSize
=
Size
(
thumbSize
.
width
-
inset
,
thumbSize
.
height
-
inset
);
final
Color
trackColor
=
Color
.
lerp
(
inactiveTrackColor
,
activeTrackColor
,
currentValue
)!;
final
double
colorValue
=
CurvedAnimation
(
parent:
positionController
,
curve:
Curves
.
easeOut
,
reverseCurve:
Curves
.
easeIn
).
value
;
final
Color
trackColor
=
Color
.
lerp
(
inactiveTrackColor
,
activeTrackColor
,
colorValue
)!;
final
Color
?
trackOutlineColor
=
inactiveTrackOutlineColor
==
null
?
null
:
Color
.
lerp
(
inactiveTrackOutlineColor
,
Colors
.
transparent
,
currentValue
);
final
Color
lerpedThumbColor
=
Color
.
lerp
(
inactiveColor
,
activeColor
,
currentValue
)!;
:
Color
.
lerp
(
inactiveTrackOutlineColor
,
Colors
.
transparent
,
colorValue
);
Color
lerpedThumbColor
;
if
(!
reaction
.
isDismissed
)
{
lerpedThumbColor
=
Color
.
lerp
(
inactivePressedColor
,
activePressedColor
,
colorValue
)!;
}
else
if
(
positionController
.
status
==
AnimationStatus
.
forward
)
{
lerpedThumbColor
=
Color
.
lerp
(
inactivePressedColor
,
activeColor
,
colorValue
)!;
}
else
if
(
positionController
.
status
==
AnimationStatus
.
reverse
)
{
lerpedThumbColor
=
Color
.
lerp
(
inactiveColor
,
activePressedColor
,
colorValue
)!;
}
else
{
lerpedThumbColor
=
Color
.
lerp
(
inactiveColor
,
activeColor
,
colorValue
)!;
}
// Blend the thumb color against a `surfaceColor` background in case the
// thumbColor is not opaque. This way we do not see through the thumb to the
// track underneath.
...
...
@@ -1289,7 +1333,7 @@ class _SwitchPainter extends ToggleablePainter {
_paintThumbWith
(
thumbPaintOffset
,
canvas
,
c
urrent
Value
,
c
olor
Value
,
thumbColor
,
thumbImage
,
thumbErrorListener
,
...
...
@@ -1381,7 +1425,7 @@ class _SwitchPainter extends ToggleablePainter {
thumbPainter
.
paint
(
canvas
,
thumbPaintOffset
+
Offset
(
0
,
inset
)
,
thumbPaintOffset
,
configuration
.
copyWith
(
size:
thumbSize
),
);
...
...
packages/flutter/test/material/switch_test.dart
View file @
24499077
...
...
@@ -2438,6 +2438,89 @@ void main() {
);
});
testWidgets
(
'Switch thumb shows correct pressed color - M3'
,
(
WidgetTester
tester
)
async
{
final
ThemeData
themeData
=
ThemeData
(
useMaterial3:
true
);
final
ColorScheme
colors
=
themeData
.
colorScheme
;
Widget
buildApp
({
bool
enabled
=
true
,
bool
value
=
true
})
{
return
MaterialApp
(
theme:
themeData
,
home:
Material
(
child:
Center
(
child:
StatefulBuilder
(
builder:
(
BuildContext
context
,
StateSetter
setState
)
{
return
Switch
(
value:
value
,
onChanged:
enabled
?
(
bool
newValue
)
{
setState
(()
{
value
=
newValue
;
});
}
:
null
,
);
}),
),
),
);
}
await
tester
.
pumpWidget
(
buildApp
());
await
tester
.
press
(
find
.
byType
(
Switch
));
await
tester
.
pumpAndSettle
();
expect
(
Material
.
of
(
tester
.
element
(
find
.
byType
(
Switch
))),
paints
..
rrect
(
color:
colors
.
primary
,
// track color
style:
PaintingStyle
.
fill
,
)..
rrect
(
color:
Colors
.
transparent
,
// track outline color
style:
PaintingStyle
.
stroke
,
)..
rrect
(
color:
colors
.
primaryContainer
,
rrect:
RRect
.
fromLTRBR
(
26.0
,
10.0
,
54.0
,
38.0
,
const
Radius
.
circular
(
14.0
))),
);
await
tester
.
pumpWidget
(
Container
());
await
tester
.
pumpWidget
(
buildApp
(
value:
false
));
await
tester
.
press
(
find
.
byType
(
Switch
));
await
tester
.
pumpAndSettle
();
expect
(
Material
.
of
(
tester
.
element
(
find
.
byType
(
Switch
))),
paints
..
rrect
(
color:
colors
.
surfaceVariant
,
// track color
style:
PaintingStyle
.
fill
)..
rrect
(
color:
colors
.
outline
,
// track outline color
style:
PaintingStyle
.
stroke
,
)..
rrect
(
color:
colors
.
onSurfaceVariant
),
);
await
tester
.
pumpWidget
(
Container
());
await
tester
.
pumpWidget
(
buildApp
(
enabled:
false
));
await
tester
.
press
(
find
.
byType
(
Switch
));
await
tester
.
pumpAndSettle
();
expect
(
Material
.
of
(
tester
.
element
(
find
.
byType
(
Switch
))),
paints
..
rrect
(
color:
colors
.
onSurface
.
withOpacity
(
0.12
),
// track color
style:
PaintingStyle
.
fill
,
)..
rrect
(
color:
Colors
.
transparent
,
// track outline color
style:
PaintingStyle
.
stroke
,
)..
rrect
(
color:
colors
.
surface
.
withOpacity
(
1.0
)),
);
await
tester
.
pumpWidget
(
Container
());
await
tester
.
pumpWidget
(
buildApp
(
enabled:
false
,
value:
false
));
await
tester
.
press
(
find
.
byType
(
Switch
));
await
tester
.
pumpAndSettle
();
expect
(
Material
.
of
(
tester
.
element
(
find
.
byType
(
Switch
))),
paints
..
rrect
(
color:
colors
.
surfaceVariant
.
withOpacity
(
0.12
),
// track color
style:
PaintingStyle
.
fill
,
)..
rrect
(
color:
colors
.
onSurface
.
withOpacity
(
0.12
),
// track outline color
style:
PaintingStyle
.
stroke
,
)..
rrect
(
color:
Color
.
alphaBlend
(
colors
.
onSurface
.
withOpacity
(
0.38
),
colors
.
surface
)),
);
},
variant:
TargetPlatformVariant
.
mobile
());
testWidgets
(
'Switch thumb color resolves in active/enabled states - M3'
,
(
WidgetTester
tester
)
async
{
final
ThemeData
themeData
=
ThemeData
(
useMaterial3:
true
,
colorSchemeSeed:
const
Color
(
0xff6750a4
),
brightness:
Brightness
.
light
);
final
ColorScheme
colors
=
themeData
.
colorScheme
;
...
...
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