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
bbb080b3
Unverified
Commit
bbb080b3
authored
Oct 08, 2018
by
Hans Muller
Committed by
GitHub
Oct 08, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Material Switch optionally adapts per platform: Switch.adaptive() (#22688)
parent
d422e85f
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
140 additions
and
20 deletions
+140
-20
selection_controls_demo.dart
...er_gallery/lib/demo/material/selection_controls_demo.dart
+3
-3
switch.dart
packages/flutter/lib/src/material/switch.dart
+93
-17
switch_test.dart
packages/flutter/test/material/switch_test.dart
+44
-0
No files found.
examples/flutter_gallery/lib/demo/material/selection_controls_demo.dart
View file @
bbb080b3
...
@@ -187,7 +187,7 @@ class _SelectionControlsDemoState extends State<SelectionControlsDemo> {
...
@@ -187,7 +187,7 @@ class _SelectionControlsDemoState extends State<SelectionControlsDemo> {
child:
Row
(
child:
Row
(
mainAxisSize:
MainAxisSize
.
min
,
mainAxisSize:
MainAxisSize
.
min
,
children:
<
Widget
>[
children:
<
Widget
>[
Switch
(
Switch
.
adaptive
(
value:
switchValue
,
value:
switchValue
,
onChanged:
(
bool
value
)
{
onChanged:
(
bool
value
)
{
setState
(()
{
setState
(()
{
...
@@ -196,8 +196,8 @@ class _SelectionControlsDemoState extends State<SelectionControlsDemo> {
...
@@ -196,8 +196,8 @@ class _SelectionControlsDemoState extends State<SelectionControlsDemo> {
}
}
),
),
// Disabled switches
// Disabled switches
const
Switch
(
value:
true
,
onChanged:
null
),
const
Switch
.
adaptive
(
value:
true
,
onChanged:
null
),
const
Switch
(
value:
false
,
onChanged:
null
)
const
Switch
.
adaptive
(
value:
false
,
onChanged:
null
),
],
],
),
),
);
);
...
...
packages/flutter/lib/src/material/switch.dart
View file @
bbb080b3
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
import
'package:flutter/cupertino.dart'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/gestures.dart'
;
import
'package:flutter/gestures.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/rendering.dart'
;
...
@@ -23,6 +24,8 @@ const double _kSwitchWidth = _kTrackWidth - 2 * _kTrackRadius + 2 * kRadialReact
...
@@ -23,6 +24,8 @@ const double _kSwitchWidth = _kTrackWidth - 2 * _kTrackRadius + 2 * kRadialReact
const
double
_kSwitchHeight
=
2
*
kRadialReactionRadius
+
8.0
;
const
double
_kSwitchHeight
=
2
*
kRadialReactionRadius
+
8.0
;
const
double
_kSwitchHeightCollapsed
=
2
*
kRadialReactionRadius
;
const
double
_kSwitchHeightCollapsed
=
2
*
kRadialReactionRadius
;
enum
_SwitchType
{
material
,
adaptive
}
/// A material design switch.
/// A material design switch.
///
///
/// Used to toggle the on/off state of a single setting.
/// Used to toggle the on/off state of a single setting.
...
@@ -65,7 +68,30 @@ class Switch extends StatefulWidget {
...
@@ -65,7 +68,30 @@ class Switch extends StatefulWidget {
this
.
activeThumbImage
,
this
.
activeThumbImage
,
this
.
inactiveThumbImage
,
this
.
inactiveThumbImage
,
this
.
materialTapTargetSize
,
this
.
materialTapTargetSize
,
})
:
super
(
key:
key
);
})
:
_switchType
=
_SwitchType
.
material
,
super
(
key:
key
);
/// Creates a [CupertinoSwitch] if the target platform is iOS, creates a
/// material design switch otherwise.
///
/// If a [CupertinoSwitch] is created, the following parameters are
/// ignored: [activeTrackColor], [inactiveThumbColor], [inactiveTrackColor],
/// [activeThumbImage], [inactiveThumbImage], [materialTapTargetSize].
///
/// The target platform is based on the current [Theme]: [ThemeData.platform].
const
Switch
.
adaptive
({
Key
key
,
@required
this
.
value
,
@required
this
.
onChanged
,
this
.
activeColor
,
this
.
activeTrackColor
,
this
.
inactiveThumbColor
,
this
.
inactiveTrackColor
,
this
.
activeThumbImage
,
this
.
inactiveThumbImage
,
this
.
materialTapTargetSize
,
})
:
_switchType
=
_SwitchType
.
adaptive
,
super
(
key:
key
);
/// Whether this switch is on or off.
/// Whether this switch is on or off.
///
///
...
@@ -104,22 +130,32 @@ class Switch extends StatefulWidget {
...
@@ -104,22 +130,32 @@ class Switch extends StatefulWidget {
/// The color to use on the track when this switch is on.
/// The color to use on the track when this switch is on.
///
///
/// Defaults to [ThemeData.toggleableActiveColor] with the opacity set at 50%.
/// Defaults to [ThemeData.toggleableActiveColor] with the opacity set at 50%.
///
/// Ignored if this switch is created with [Switch.adaptive].
final
Color
activeTrackColor
;
final
Color
activeTrackColor
;
/// The color to use on the thumb when this switch is off.
/// The color to use on the thumb when this switch is off.
///
///
/// Defaults to the colors described in the Material design specification.
/// Defaults to the colors described in the Material design specification.
///
/// Ignored if this switch is created with [Switch.adaptive].
final
Color
inactiveThumbColor
;
final
Color
inactiveThumbColor
;
/// The color to use on the track when this switch is off.
/// The color to use on the track when this switch is off.
///
///
/// Defaults to the colors described in the Material design specification.
/// Defaults to the colors described in the Material design specification.
///
/// Ignored if this switch is created with [Switch.adaptive].
final
Color
inactiveTrackColor
;
final
Color
inactiveTrackColor
;
/// An image to use on the thumb of this switch when the switch is on.
/// An image to use on the thumb of this switch when the switch is on.
///
/// Ignored if this switch is created with [Switch.adaptive].
final
ImageProvider
activeThumbImage
;
final
ImageProvider
activeThumbImage
;
/// An image to use on the thumb of this switch when the switch is off.
/// An image to use on the thumb of this switch when the switch is off.
///
/// Ignored if this switch is created with [Switch.adaptive].
final
ImageProvider
inactiveThumbImage
;
final
ImageProvider
inactiveThumbImage
;
/// Configures the minimum size of the tap target.
/// Configures the minimum size of the tap target.
...
@@ -131,6 +167,8 @@ class Switch extends StatefulWidget {
...
@@ -131,6 +167,8 @@ class Switch extends StatefulWidget {
/// * [MaterialTapTargetSize], for a description of how this affects tap targets.
/// * [MaterialTapTargetSize], for a description of how this affects tap targets.
final
MaterialTapTargetSize
materialTapTargetSize
;
final
MaterialTapTargetSize
materialTapTargetSize
;
final
_SwitchType
_switchType
;
@override
@override
_SwitchState
createState
()
=>
_SwitchState
();
_SwitchState
createState
()
=>
_SwitchState
();
...
@@ -143,13 +181,25 @@ class Switch extends StatefulWidget {
...
@@ -143,13 +181,25 @@ class Switch extends StatefulWidget {
}
}
class
_SwitchState
extends
State
<
Switch
>
with
TickerProviderStateMixin
{
class
_SwitchState
extends
State
<
Switch
>
with
TickerProviderStateMixin
{
@override
Size
getSwitchSize
(
ThemeData
theme
)
{
Widget
build
(
BuildContext
context
)
{
switch
(
widget
.
materialTapTargetSize
??
theme
.
materialTapTargetSize
)
{
case
MaterialTapTargetSize
.
padded
:
return
const
Size
(
_kSwitchWidth
,
_kSwitchHeight
);
break
;
case
MaterialTapTargetSize
.
shrinkWrap
:
return
const
Size
(
_kSwitchWidth
,
_kSwitchHeightCollapsed
);
break
;
}
assert
(
false
);
return
null
;
}
Widget
buildMaterialSwitch
(
BuildContext
context
)
{
assert
(
debugCheckHasMaterial
(
context
));
assert
(
debugCheckHasMaterial
(
context
));
final
ThemeData
theme
Data
=
Theme
.
of
(
context
);
final
ThemeData
theme
=
Theme
.
of
(
context
);
final
bool
isDark
=
theme
Data
.
brightness
==
Brightness
.
dark
;
final
bool
isDark
=
theme
.
brightness
==
Brightness
.
dark
;
final
Color
activeThumbColor
=
widget
.
activeColor
??
theme
Data
.
toggleableActiveColor
;
final
Color
activeThumbColor
=
widget
.
activeColor
??
theme
.
toggleableActiveColor
;
final
Color
activeTrackColor
=
widget
.
activeTrackColor
??
activeThumbColor
.
withAlpha
(
0x80
);
final
Color
activeTrackColor
=
widget
.
activeTrackColor
??
activeThumbColor
.
withAlpha
(
0x80
);
Color
inactiveThumbColor
;
Color
inactiveThumbColor
;
...
@@ -162,16 +212,6 @@ class _SwitchState extends State<Switch> with TickerProviderStateMixin {
...
@@ -162,16 +212,6 @@ class _SwitchState extends State<Switch> with TickerProviderStateMixin {
inactiveThumbColor
=
widget
.
inactiveThumbColor
??
(
isDark
?
Colors
.
grey
.
shade800
:
Colors
.
grey
.
shade400
);
inactiveThumbColor
=
widget
.
inactiveThumbColor
??
(
isDark
?
Colors
.
grey
.
shade800
:
Colors
.
grey
.
shade400
);
inactiveTrackColor
=
widget
.
inactiveTrackColor
??
(
isDark
?
Colors
.
white10
:
Colors
.
black12
);
inactiveTrackColor
=
widget
.
inactiveTrackColor
??
(
isDark
?
Colors
.
white10
:
Colors
.
black12
);
}
}
Size
size
;
switch
(
widget
.
materialTapTargetSize
??
themeData
.
materialTapTargetSize
)
{
case
MaterialTapTargetSize
.
padded
:
size
=
const
Size
(
_kSwitchWidth
,
_kSwitchHeight
);
break
;
case
MaterialTapTargetSize
.
shrinkWrap
:
size
=
const
Size
(
_kSwitchWidth
,
_kSwitchHeightCollapsed
);
break
;
}
final
BoxConstraints
additionalConstraints
=
BoxConstraints
.
tight
(
size
);
return
_SwitchRenderObjectWidget
(
return
_SwitchRenderObjectWidget
(
value:
widget
.
value
,
value:
widget
.
value
,
...
@@ -183,10 +223,46 @@ class _SwitchState extends State<Switch> with TickerProviderStateMixin {
...
@@ -183,10 +223,46 @@ class _SwitchState extends State<Switch> with TickerProviderStateMixin {
inactiveTrackColor:
inactiveTrackColor
,
inactiveTrackColor:
inactiveTrackColor
,
configuration:
createLocalImageConfiguration
(
context
),
configuration:
createLocalImageConfiguration
(
context
),
onChanged:
widget
.
onChanged
,
onChanged:
widget
.
onChanged
,
additionalConstraints:
additionalConstraints
,
additionalConstraints:
BoxConstraints
.
tight
(
getSwitchSize
(
theme
))
,
vsync:
this
,
vsync:
this
,
);
);
}
}
Widget
buildCupertinoSwitch
(
BuildContext
context
)
{
final
Size
size
=
getSwitchSize
(
Theme
.
of
(
context
));
return
Container
(
width:
size
.
width
,
// Same size as the Material switch.
height:
size
.
height
,
alignment:
Alignment
.
center
,
child:
CupertinoSwitch
(
value:
widget
.
value
,
onChanged:
widget
.
onChanged
,
activeColor:
widget
.
activeColor
,
),
);
}
@override
Widget
build
(
BuildContext
context
)
{
switch
(
widget
.
_switchType
)
{
case
_SwitchType
.
material
:
return
buildMaterialSwitch
(
context
);
case
_SwitchType
.
adaptive
:
{
final
ThemeData
theme
=
Theme
.
of
(
context
);
assert
(
theme
.
platform
!=
null
);
switch
(
theme
.
platform
)
{
case
TargetPlatform
.
android
:
case
TargetPlatform
.
fuchsia
:
return
buildMaterialSwitch
(
context
);
case
TargetPlatform
.
iOS
:
return
buildCupertinoSwitch
(
context
);
}
}
}
assert
(
false
);
return
null
;
}
}
}
class
_SwitchRenderObjectWidget
extends
LeafRenderObjectWidget
{
class
_SwitchRenderObjectWidget
extends
LeafRenderObjectWidget
{
...
...
packages/flutter/test/material/switch_test.dart
View file @
bbb080b3
...
@@ -2,6 +2,8 @@
...
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
import
'package:flutter/cupertino.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/services.dart'
;
import
'package:flutter/services.dart'
;
...
@@ -485,4 +487,46 @@ void main() {
...
@@ -485,4 +487,46 @@ void main() {
semanticsTester
.
dispose
();
semanticsTester
.
dispose
();
SystemChannels
.
accessibility
.
setMockMessageHandler
(
null
);
SystemChannels
.
accessibility
.
setMockMessageHandler
(
null
);
});
});
testWidgets
(
'Switch.adaptive'
,
(
WidgetTester
tester
)
async
{
bool
value
=
false
;
Widget
buildFrame
(
TargetPlatform
platform
)
{
return
MaterialApp
(
theme:
ThemeData
(
platform:
platform
),
home:
StatefulBuilder
(
builder:
(
BuildContext
context
,
StateSetter
setState
)
{
return
Material
(
child:
Center
(
child:
Switch
.
adaptive
(
value:
value
,
onChanged:
(
bool
newValue
)
{
setState
(()
{
value
=
newValue
;
});
},
),
),
);
},
),
);
}
await
tester
.
pumpWidget
(
buildFrame
(
TargetPlatform
.
iOS
));
expect
(
find
.
byType
(
CupertinoSwitch
),
findsOneWidget
);
expect
(
value
,
isFalse
);
await
tester
.
tap
(
find
.
byType
(
Switch
));
expect
(
value
,
isTrue
);
await
tester
.
pumpWidget
(
buildFrame
(
TargetPlatform
.
android
));
await
tester
.
pumpAndSettle
();
// Finish the theme change animation.
expect
(
find
.
byType
(
CupertinoSwitch
),
findsNothing
);
expect
(
value
,
isTrue
);
await
tester
.
tap
(
find
.
byType
(
Switch
));
expect
(
value
,
isFalse
);
});
}
}
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