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
f5be639e
Unverified
Commit
f5be639e
authored
Apr 07, 2022
by
Kate Lovett
Committed by
GitHub
Apr 07, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "Refactor `ToggleButtons` (remove `RawMaterialButton`) (#99493)" (#101536)
This reverts commit
0b216f7a
.
parent
b528310f
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
460 additions
and
231 deletions
+460
-231
toggle_buttons.dart
packages/flutter/lib/src/material/toggle_buttons.dart
+415
-158
toggle_buttons_test.dart
packages/flutter/test/material/toggle_buttons_test.dart
+30
-58
toggle_buttons_theme_test.dart
...ages/flutter/test/material/toggle_buttons_theme_test.dart
+15
-15
No files found.
packages/flutter/lib/src/material/toggle_buttons.dart
View file @
f5be639e
...
...
@@ -8,12 +8,11 @@ import 'package:flutter/foundation.dart';
import
'package:flutter/rendering.dart'
;
import
'package:flutter/widgets.dart'
;
import
'button
_style
.dart'
;
import
'button.dart'
;
import
'color_scheme.dart'
;
import
'constants.dart'
;
import
'
ink_ripple
.dart'
;
import
'
debug
.dart'
;
import
'material_state.dart'
;
import
'text_button.dart'
;
import
'theme.dart'
;
import
'theme_data.dart'
;
import
'toggle_buttons_theme.dart'
;
...
...
@@ -193,21 +192,10 @@ class ToggleButtons extends StatelessWidget {
this
.
borderWidth
,
this
.
direction
=
Axis
.
horizontal
,
this
.
verticalDirection
=
VerticalDirection
.
down
,
this
.
style
,
})
:
assert
(
children
!=
null
),
assert
(
isSelected
!=
null
),
assert
(
children
.
length
==
isSelected
.
length
),
assert
(
!(
style
!=
null
&&
(
mouseCursor
!=
null
||
textStyle
!=
null
||
fillColor
!=
null
||
focusColor
!=
null
||
highlightColor
!=
null
||
hoverColor
!=
null
||
splashColor
!=
null
)),
'You can only pass [style] or textStyle, fillColor, splashColor properties, not both.'
),
assert
(
direction
!=
null
),
assert
(
direction
==
Axis
.
horizontal
||
verticalDirection
!=
null
),
super
(
key:
key
);
...
...
@@ -429,14 +417,6 @@ class ToggleButtons extends StatelessWidget {
/// the buttons starting from the first or last child from top to bottom.
final
VerticalDirection
verticalDirection
;
/// Customizes this toggle button's appearance.
///
/// When implemented this overrides the individual customizable properties
/// of toggle buttons such as [selectedColor], [disabledColor], [hoverColor].
///
/// Null by default.
final
ButtonStyle
?
style
;
// Determines if this is the first child that is being laid out
// by the render object, _not_ the order of the children in its list.
bool
_isFirstButton
(
int
index
,
int
length
,
TextDirection
textDirection
)
{
...
...
@@ -688,87 +668,33 @@ class ToggleButtons extends StatelessWidget {
final
BorderSide
borderSide
=
_getBorderSide
(
index
,
theme
,
toggleButtonsTheme
);
final
BorderSide
trailingBorderSide
=
_getTrailingBorderSide
(
index
,
theme
,
toggleButtonsTheme
);
final
Set
<
MaterialState
>
states
=
<
MaterialState
>{
if
(
isSelected
[
index
]
&&
onPressed
!=
null
)
MaterialState
.
selected
,
if
(
onPressed
==
null
)
MaterialState
.
disabled
,
};
final
Color
effectiveFillColor
=
_ResolveFillColor
(
fillColor
??
toggleButtonsTheme
.
fillColor
).
resolve
(
states
)
??
_DefaultFillColor
(
theme
.
colorScheme
).
resolve
(
states
);
final
Color
currentColor
;
if
(
onPressed
!=
null
&&
isSelected
[
index
])
{
currentColor
=
selectedColor
??
toggleButtonsTheme
.
selectedColor
??
theme
.
colorScheme
.
primary
;
}
else
if
(
onPressed
!=
null
&&
!
isSelected
[
index
])
{
currentColor
=
color
??
toggleButtonsTheme
.
color
??
theme
.
colorScheme
.
onSurface
.
withOpacity
(
0.87
);
}
else
{
currentColor
=
disabledColor
??
toggleButtonsTheme
.
disabledColor
??
theme
.
colorScheme
.
onSurface
.
withOpacity
(
0.38
);
}
final
TextStyle
currentTextStyle
=
textStyle
??
toggleButtonsTheme
.
textStyle
??
theme
.
textTheme
.
bodyText2
!;
final
BoxConstraints
currentConstraints
=
constraints
??
toggleButtonsTheme
.
constraints
??
const
BoxConstraints
(
minWidth:
kMinInteractiveDimension
,
minHeight:
kMinInteractiveDimension
,
);
return
_SelectToggleButton
(
return
_ToggleButton
(
selected:
isSelected
[
index
],
textStyle:
textStyle
,
constraints:
constraints
,
color:
color
,
selectedColor:
selectedColor
,
disabledColor:
disabledColor
,
fillColor:
fillColor
,
focusColor:
focusColor
??
toggleButtonsTheme
.
focusColor
,
highlightColor:
highlightColor
??
toggleButtonsTheme
.
highlightColor
,
hoverColor:
hoverColor
??
toggleButtonsTheme
.
hoverColor
,
splashColor:
splashColor
??
toggleButtonsTheme
.
splashColor
,
focusNode:
focusNodes
!=
null
?
focusNodes
![
index
]
:
null
,
onPressed:
onPressed
!=
null
?
()
{
onPressed
!(
index
);}
:
null
,
mouseCursor:
mouseCursor
,
leadingBorderSide:
leadingBorderSide
,
borderSide:
borderSide
,
trailingBorderSide:
trailingBorderSide
,
borderRadius:
edgeBorderRadius
,
clipRadius:
clipBorderRadius
,
isFirstButton:
index
==
0
,
isLastButton:
index
==
children
.
length
-
1
,
direction:
direction
,
verticalDirection:
verticalDirection
,
child:
ClipRRect
(
borderRadius:
clipBorderRadius
,
child:
TextButton
(
focusNode:
focusNodes
!=
null
?
focusNodes
![
index
]
:
null
,
style:
ButtonStyle
(
backgroundColor:
MaterialStateProperty
.
all
<
Color
?>(
effectiveFillColor
),
foregroundColor:
MaterialStateProperty
.
all
<
Color
?>(
currentColor
),
overlayColor:
_ToggleButtonDefaultOverlay
(
selected:
onPressed
!=
null
&&
isSelected
[
index
],
unselected:
onPressed
!=
null
&&
!
isSelected
[
index
],
colorScheme:
theme
.
colorScheme
,
disabledColor:
disabledColor
??
toggleButtonsTheme
.
disabledColor
,
focusColor:
focusColor
??
toggleButtonsTheme
.
focusColor
,
highlightColor:
highlightColor
??
toggleButtonsTheme
.
highlightColor
,
hoverColor:
hoverColor
??
toggleButtonsTheme
.
hoverColor
,
splashColor:
splashColor
??
toggleButtonsTheme
.
splashColor
,
),
elevation:
MaterialStateProperty
.
all
<
double
>(
0
),
textStyle:
MaterialStateProperty
.
all
<
TextStyle
?>(
currentTextStyle
.
copyWith
(
color:
currentColor
,
)),
padding:
MaterialStateProperty
.
all
<
EdgeInsetsGeometry
>(
EdgeInsets
.
zero
),
minimumSize:
MaterialStateProperty
.
all
<
Size
?>(
Size
(
currentConstraints
.
minWidth
,
currentConstraints
.
minHeight
)),
maximumSize:
MaterialStateProperty
.
all
<
Size
?>(
Size
(
currentConstraints
.
maxWidth
,
currentConstraints
.
maxHeight
)),
shape:
MaterialStateProperty
.
all
<
OutlinedBorder
>(
const
RoundedRectangleBorder
()),
mouseCursor:
MaterialStateProperty
.
all
<
MouseCursor
?>(
mouseCursor
),
visualDensity:
VisualDensity
.
adaptivePlatformDensity
,
tapTargetSize:
tapTargetSize
??
theme
.
materialTapTargetSize
,
animationDuration:
kThemeChangeDuration
,
enableFeedback:
true
,
alignment:
Alignment
.
center
,
splashFactory:
InkRipple
.
splashFactory
,
),
onPressed:
onPressed
!=
null
?
()
{
onPressed
!(
index
);}
:
null
,
child:
children
[
index
],
),
),
);
});
...
...
@@ -789,8 +715,18 @@ class ToggleButtons extends StatelessWidget {
),
);
final
MaterialTapTargetSize
resolvedTapTargetSize
=
tapTargetSize
??
theme
.
materialTapTargetSize
;
switch
(
resolvedTapTargetSize
)
{
case
MaterialTapTargetSize
.
padded
:
return
_InputPadding
(
minSize:
const
Size
(
kMinInteractiveDimension
,
kMinInteractiveDimension
),
direction:
direction
,
child:
result
,
);
case
MaterialTapTargetSize
.
shrinkWrap
:
return
result
;
}
}
@override
void
debugFillProperties
(
DiagnosticPropertiesBuilder
properties
)
{
...
...
@@ -819,6 +755,251 @@ class ToggleButtons extends StatelessWidget {
}
}
/// An individual toggle button, otherwise known as a segmented button.
///
/// This button is used by [ToggleButtons] to implement a set of segmented controls.
class
_ToggleButton
extends
StatelessWidget
{
/// Creates a toggle button based on [RawMaterialButton].
///
/// This class adds some logic to distinguish between enabled, active, and
/// disabled states, to determine the appropriate colors to use.
///
/// It takes in a [shape] property to modify the borders of the button,
/// which is used by [ToggleButtons] to customize borders based on the
/// order in which this button appears in the list.
const
_ToggleButton
({
Key
?
key
,
this
.
selected
=
false
,
this
.
textStyle
,
this
.
constraints
,
this
.
color
,
this
.
selectedColor
,
this
.
disabledColor
,
required
this
.
fillColor
,
required
this
.
focusColor
,
required
this
.
highlightColor
,
required
this
.
hoverColor
,
required
this
.
splashColor
,
this
.
focusNode
,
this
.
onPressed
,
this
.
mouseCursor
,
required
this
.
leadingBorderSide
,
required
this
.
borderSide
,
required
this
.
trailingBorderSide
,
required
this
.
borderRadius
,
required
this
.
clipRadius
,
required
this
.
isFirstButton
,
required
this
.
isLastButton
,
required
this
.
direction
,
required
this
.
verticalDirection
,
required
this
.
child
,
})
:
super
(
key:
key
);
/// Determines if the button is displayed as active/selected or enabled.
final
bool
selected
;
/// The [TextStyle] to apply to any text that appears in this button.
final
TextStyle
?
textStyle
;
/// Defines the button's size.
///
/// Typically used to constrain the button's minimum size.
final
BoxConstraints
?
constraints
;
/// The color for [Text] and [Icon] widgets if the button is enabled.
///
/// If [selected] is false and [onPressed] is not null, this color will be used.
final
Color
?
color
;
/// The color for [Text] and [Icon] widgets if the button is selected.
///
/// If [selected] is true and [onPressed] is not null, this color will be used.
final
Color
?
selectedColor
;
/// The color for [Text] and [Icon] widgets if the button is disabled.
///
/// If [onPressed] is null, this color will be used.
final
Color
?
disabledColor
;
/// The color of the button's [Material].
final
Color
?
fillColor
;
/// The color for the button's [Material] when it has the input focus.
final
Color
?
focusColor
;
/// The color for the button's [Material] when a pointer is hovering over it.
final
Color
?
hoverColor
;
/// The highlight color for the button's [InkWell].
final
Color
?
highlightColor
;
/// The splash color for the button's [InkWell].
final
Color
?
splashColor
;
/// {@macro flutter.widgets.Focus.focusNode}
final
FocusNode
?
focusNode
;
/// Called when the button is tapped or otherwise activated.
///
/// If this is null, the button will be disabled, see [enabled].
final
VoidCallback
?
onPressed
;
/// {@macro flutter.material.RawMaterialButton.mouseCursor}
///
/// If this property is null, [MaterialStateMouseCursor.clickable] will be used.
final
MouseCursor
?
mouseCursor
;
/// The width and color of the button's leading side border.
final
BorderSide
leadingBorderSide
;
/// If [direction] is [Axis.horizontal], this corresponds the width and color
/// of the button's top and bottom side borders.
///
/// If [direction] is [Axis.vertical], this corresponds the width and color
/// of the button's left and right side borders.
final
BorderSide
borderSide
;
/// The width and color of the button's trailing side border.
final
BorderSide
trailingBorderSide
;
/// The border radii of each corner of the button.
final
BorderRadius
borderRadius
;
/// The corner radii used to clip the button's contents.
///
/// This is used to have the button's contents be properly clipped taking
/// the [borderRadius] and the border's width into account.
final
BorderRadius
clipRadius
;
/// Whether or not this toggle button is the first button in the list.
final
bool
isFirstButton
;
/// Whether or not this toggle button is the last button in the list.
final
bool
isLastButton
;
/// The direction along which the buttons are rendered.
final
Axis
direction
;
/// If [direction] is [Axis.vertical], this property defines whether or not this button in its list
/// of buttons is laid out starting from top to bottom or from bottom to top.
final
VerticalDirection
verticalDirection
;
/// The button's label, which is usually an [Icon] or a [Text] widget.
final
Widget
child
;
Color
_resolveColor
(
Set
<
MaterialState
>
states
,
MaterialStateProperty
<
Color
?>
widgetColor
,
MaterialStateProperty
<
Color
?>
themeColor
,
MaterialStateProperty
<
Color
>
defaultColor
)
{
return
widgetColor
.
resolve
(
states
)
??
themeColor
.
resolve
(
states
)
??
defaultColor
.
resolve
(
states
);
}
@override
Widget
build
(
BuildContext
context
)
{
assert
(
debugCheckHasMaterial
(
context
));
final
Color
currentColor
;
Color
?
currentFocusColor
;
Color
?
currentHoverColor
;
Color
?
currentSplashColor
;
final
ThemeData
theme
=
Theme
.
of
(
context
);
final
ToggleButtonsThemeData
toggleButtonsTheme
=
ToggleButtonsTheme
.
of
(
context
);
final
Set
<
MaterialState
>
states
=
<
MaterialState
>{
if
(
selected
&&
onPressed
!=
null
)
MaterialState
.
selected
,
if
(
onPressed
==
null
)
MaterialState
.
disabled
,
};
final
Color
currentFillColor
=
_resolveColor
(
states
,
_ResolveFillColor
(
fillColor
),
_ResolveFillColor
(
toggleButtonsTheme
.
fillColor
),
_DefaultFillColor
(
theme
.
colorScheme
),
);
if
(
onPressed
!=
null
&&
selected
)
{
currentColor
=
selectedColor
??
toggleButtonsTheme
.
selectedColor
??
theme
.
colorScheme
.
primary
;
currentFocusColor
=
focusColor
??
toggleButtonsTheme
.
focusColor
??
theme
.
colorScheme
.
primary
.
withOpacity
(
0.12
);
currentHoverColor
=
hoverColor
??
toggleButtonsTheme
.
hoverColor
??
theme
.
colorScheme
.
primary
.
withOpacity
(
0.04
);
currentSplashColor
=
splashColor
??
toggleButtonsTheme
.
splashColor
??
theme
.
colorScheme
.
primary
.
withOpacity
(
0.16
);
}
else
if
(
onPressed
!=
null
&&
!
selected
)
{
currentColor
=
color
??
toggleButtonsTheme
.
color
??
theme
.
colorScheme
.
onSurface
.
withOpacity
(
0.87
);
currentFocusColor
=
focusColor
??
toggleButtonsTheme
.
focusColor
??
theme
.
colorScheme
.
onSurface
.
withOpacity
(
0.12
);
currentHoverColor
=
hoverColor
??
toggleButtonsTheme
.
hoverColor
??
theme
.
colorScheme
.
onSurface
.
withOpacity
(
0.04
);
currentSplashColor
=
splashColor
??
toggleButtonsTheme
.
splashColor
??
theme
.
colorScheme
.
onSurface
.
withOpacity
(
0.16
);
}
else
{
currentColor
=
disabledColor
??
toggleButtonsTheme
.
disabledColor
??
theme
.
colorScheme
.
onSurface
.
withOpacity
(
0.38
);
}
final
TextStyle
currentTextStyle
=
textStyle
??
toggleButtonsTheme
.
textStyle
??
theme
.
textTheme
.
bodyText2
!;
final
BoxConstraints
currentConstraints
=
constraints
??
toggleButtonsTheme
.
constraints
??
const
BoxConstraints
(
minWidth:
kMinInteractiveDimension
,
minHeight:
kMinInteractiveDimension
);
final
Widget
result
=
ClipRRect
(
borderRadius:
clipRadius
,
child:
RawMaterialButton
(
textStyle:
currentTextStyle
.
copyWith
(
color:
currentColor
,
),
constraints:
currentConstraints
,
elevation:
0.0
,
fillColor:
currentFillColor
,
focusColor:
currentFocusColor
,
focusElevation:
0
,
highlightColor:
highlightColor
??
theme
.
colorScheme
.
surface
.
withOpacity
(
0.0
),
highlightElevation:
0.0
,
hoverColor:
currentHoverColor
,
hoverElevation:
0
,
splashColor:
currentSplashColor
,
focusNode:
focusNode
,
materialTapTargetSize:
MaterialTapTargetSize
.
shrinkWrap
,
onPressed:
onPressed
,
mouseCursor:
mouseCursor
,
child:
child
,
),
);
return
_SelectToggleButton
(
key:
key
,
leadingBorderSide:
leadingBorderSide
,
borderSide:
borderSide
,
trailingBorderSide:
trailingBorderSide
,
borderRadius:
borderRadius
,
isFirstButton:
isFirstButton
,
isLastButton:
isLastButton
,
direction:
direction
,
verticalDirection:
verticalDirection
,
child:
result
,
);
}
@override
void
debugFillProperties
(
DiagnosticPropertiesBuilder
properties
)
{
super
.
debugFillProperties
(
properties
);
properties
.
add
(
FlagProperty
(
'selected'
,
value:
selected
,
ifTrue:
'Button is selected'
,
ifFalse:
'Button is unselected'
,
));
}
}
@immutable
class
_ResolveFillColor
extends
MaterialStateProperty
<
Color
?>
with
Diagnosticable
{
_ResolveFillColor
(
this
.
primary
);
...
...
@@ -849,68 +1030,6 @@ class _DefaultFillColor extends MaterialStateProperty<Color> with Diagnosticable
}
}
@immutable
class
_ToggleButtonDefaultOverlay
extends
MaterialStateProperty
<
Color
?>
{
_ToggleButtonDefaultOverlay
({
required
this
.
selected
,
required
this
.
unselected
,
this
.
colorScheme
,
this
.
focusColor
,
this
.
highlightColor
,
this
.
hoverColor
,
this
.
splashColor
,
this
.
disabledColor
,
});
final
bool
selected
;
final
bool
unselected
;
final
ColorScheme
?
colorScheme
;
final
Color
?
focusColor
;
final
Color
?
highlightColor
;
final
Color
?
hoverColor
;
final
Color
?
splashColor
;
final
Color
?
disabledColor
;
@override
Color
?
resolve
(
Set
<
MaterialState
>
states
)
{
if
(
selected
)
{
if
(
states
.
contains
(
MaterialState
.
hovered
))
{
return
hoverColor
??
colorScheme
?.
primary
.
withOpacity
(
0.04
);
}
else
if
(
states
.
contains
(
MaterialState
.
focused
))
{
return
focusColor
??
colorScheme
?.
primary
.
withOpacity
(
0.12
);
}
else
if
(
states
.
contains
(
MaterialState
.
pressed
))
{
return
splashColor
??
colorScheme
?.
primary
.
withOpacity
(
0.16
);
}
}
else
if
(
unselected
)
{
if
(
states
.
contains
(
MaterialState
.
hovered
))
{
return
hoverColor
??
colorScheme
?.
onSurface
.
withOpacity
(
0.04
);
}
else
if
(
states
.
contains
(
MaterialState
.
focused
))
{
return
focusColor
??
colorScheme
?.
onSurface
.
withOpacity
(
0.12
);
}
else
if
(
states
.
contains
(
MaterialState
.
pressed
))
{
return
splashColor
??
highlightColor
??
colorScheme
?.
onSurface
.
withOpacity
(
0.16
);
}
}
return
null
;
}
@override
String
toString
()
{
return
'''
{
selected:
hovered:
$hoverColor
, otherwise:
${colorScheme?.primary.withOpacity(0.04)}
,
focused:
$focusColor
, otherwise:
${colorScheme?.primary.withOpacity(0.12)}
,
pressed:
$splashColor
, otherwise:
${colorScheme?.primary.withOpacity(0.16)}
,
unselected:
hovered:
$hoverColor
, otherwise:
${colorScheme?.onSurface.withOpacity(0.04)}
,
focused:
$focusColor
, otherwise:
${colorScheme?.onSurface.withOpacity(0.12)}
,
pressed:
$splashColor
, otherwise:
${colorScheme?.onSurface.withOpacity(0.16)}
,
otherwise: null,
}
'''
;
}
}
class
_SelectToggleButton
extends
SingleChildRenderObjectWidget
{
const
_SelectToggleButton
({
Key
?
key
,
...
...
@@ -1457,3 +1576,141 @@ class _SelectToggleButtonRenderObject extends RenderShiftedBox {
}
}
}
/// A widget to pad the area around a [ToggleButtons]'s children.
///
/// This widget is based on a similar one used in [ButtonStyleButton] but it
/// only redirects taps along one axis to ensure the correct button is tapped
/// within the [ToggleButtons].
///
/// This ensures that a widget takes up at least as much space as the minSize
/// parameter to ensure adequate tap target size, while keeping the widget
/// visually smaller to the user.
class
_InputPadding
extends
SingleChildRenderObjectWidget
{
const
_InputPadding
({
Key
?
key
,
Widget
?
child
,
required
this
.
minSize
,
required
this
.
direction
,
})
:
super
(
key:
key
,
child:
child
);
final
Size
minSize
;
final
Axis
direction
;
@override
RenderObject
createRenderObject
(
BuildContext
context
)
{
return
_RenderInputPadding
(
minSize
,
direction
);
}
@override
void
updateRenderObject
(
BuildContext
context
,
covariant
_RenderInputPadding
renderObject
)
{
renderObject
.
minSize
=
minSize
;
renderObject
.
direction
=
direction
;
}
}
class
_RenderInputPadding
extends
RenderShiftedBox
{
_RenderInputPadding
(
this
.
_minSize
,
this
.
_direction
,
[
RenderBox
?
child
])
:
super
(
child
);
Size
get
minSize
=>
_minSize
;
Size
_minSize
;
set
minSize
(
Size
value
)
{
if
(
_minSize
==
value
)
return
;
_minSize
=
value
;
markNeedsLayout
();
}
Axis
get
direction
=>
_direction
;
Axis
_direction
;
set
direction
(
Axis
value
)
{
if
(
_direction
==
value
)
return
;
_direction
=
value
;
markNeedsLayout
();
}
@override
double
computeMinIntrinsicWidth
(
double
height
)
{
if
(
child
!=
null
)
return
math
.
max
(
child
!.
getMinIntrinsicWidth
(
height
),
minSize
.
width
);
return
0.0
;
}
@override
double
computeMinIntrinsicHeight
(
double
width
)
{
if
(
child
!=
null
)
return
math
.
max
(
child
!.
getMinIntrinsicHeight
(
width
),
minSize
.
height
);
return
0.0
;
}
@override
double
computeMaxIntrinsicWidth
(
double
height
)
{
if
(
child
!=
null
)
return
math
.
max
(
child
!.
getMaxIntrinsicWidth
(
height
),
minSize
.
width
);
return
0.0
;
}
@override
double
computeMaxIntrinsicHeight
(
double
width
)
{
if
(
child
!=
null
)
return
math
.
max
(
child
!.
getMaxIntrinsicHeight
(
width
),
minSize
.
height
);
return
0.0
;
}
Size
_computeSize
({
required
BoxConstraints
constraints
,
required
ChildLayouter
layoutChild
})
{
if
(
child
!=
null
)
{
final
Size
childSize
=
layoutChild
(
child
!,
constraints
);
final
double
height
=
math
.
max
(
childSize
.
width
,
minSize
.
width
);
final
double
width
=
math
.
max
(
childSize
.
height
,
minSize
.
height
);
return
constraints
.
constrain
(
Size
(
height
,
width
));
}
return
Size
.
zero
;
}
@override
Size
computeDryLayout
(
BoxConstraints
constraints
)
{
return
_computeSize
(
constraints:
constraints
,
layoutChild:
ChildLayoutHelper
.
dryLayoutChild
,
);
}
@override
void
performLayout
()
{
size
=
_computeSize
(
constraints:
constraints
,
layoutChild:
ChildLayoutHelper
.
layoutChild
,
);
if
(
child
!=
null
)
{
final
BoxParentData
childParentData
=
child
!.
parentData
!
as
BoxParentData
;
childParentData
.
offset
=
Alignment
.
center
.
alongOffset
(
size
-
child
!.
size
as
Offset
);
}
}
@override
bool
hitTest
(
BoxHitTestResult
result
,
{
required
Offset
position
})
{
// The super.hitTest() method also checks hitTestChildren(). We don't
// want that in this case because we've padded around the children per
// tapTargetSize.
if
(!
size
.
contains
(
position
))
{
return
false
;
}
// Only adjust one axis to ensure the correct button is tapped.
Offset
center
;
if
(
direction
==
Axis
.
horizontal
)
{
center
=
Offset
(
position
.
dx
,
child
!.
size
.
height
/
2
);
}
else
{
center
=
Offset
(
child
!.
size
.
width
/
2
,
position
.
dy
);
}
return
result
.
addWithRawTransform
(
transform:
MatrixUtils
.
forceToPoint
(
center
),
position:
center
,
hitTest:
(
BoxHitTestResult
result
,
Offset
position
)
{
assert
(
position
==
center
);
return
child
!.
hitTest
(
result
,
position:
center
);
},
);
}
}
packages/flutter/test/material/toggle_buttons_test.dart
View file @
f5be639e
...
...
@@ -26,7 +26,7 @@ void main() {
testWidgets
(
'Initial toggle state is reflected'
,
(
WidgetTester
tester
)
async
{
TextStyle
buttonTextStyle
(
String
text
)
{
return
tester
.
widget
<
DefaultTextStyle
>(
find
.
descendant
(
of:
find
.
widgetWithText
(
Text
Button
,
text
),
of:
find
.
widgetWithText
(
RawMaterial
Button
,
text
),
matching:
find
.
byType
(
DefaultTextStyle
),
)).
style
;
}
...
...
@@ -61,10 +61,11 @@ void main() {
(
WidgetTester
tester
)
async
{
TextStyle
buttonTextStyle
(
String
text
)
{
return
tester
.
widget
<
DefaultTextStyle
>(
find
.
descendant
(
of:
find
.
widgetWithText
(
Text
Button
,
text
),
of:
find
.
widgetWithText
(
RawMaterial
Button
,
text
),
matching:
find
.
byType
(
DefaultTextStyle
),
)).
style
;
}
final
List
<
bool
>
isSelected
=
<
bool
>[
false
,
true
];
final
ThemeData
theme
=
ThemeData
();
await
tester
.
pumpWidget
(
...
...
@@ -122,7 +123,7 @@ void main() {
(
WidgetTester
tester
)
async
{
TextStyle
buttonTextStyle
(
String
text
)
{
return
tester
.
widget
<
DefaultTextStyle
>(
find
.
descendant
(
of:
find
.
widgetWithText
(
Text
Button
,
text
),
of:
find
.
widgetWithText
(
RawMaterial
Button
,
text
),
matching:
find
.
byType
(
DefaultTextStyle
),
)).
style
;
}
...
...
@@ -219,14 +220,14 @@ void main() {
TextStyle
textStyle
;
textStyle
=
tester
.
widget
<
DefaultTextStyle
>(
find
.
descendant
(
of:
find
.
widgetWithText
(
Text
Button
,
'First child'
),
of:
find
.
widgetWithText
(
RawMaterial
Button
,
'First child'
),
matching:
find
.
byType
(
DefaultTextStyle
),
)).
style
;
expect
(
textStyle
.
fontFamily
,
theme
.
textTheme
.
bodyText2
!.
fontFamily
);
expect
(
textStyle
.
decoration
,
theme
.
textTheme
.
bodyText2
!.
decoration
);
textStyle
=
tester
.
widget
<
DefaultTextStyle
>(
find
.
descendant
(
of:
find
.
widgetWithText
(
Text
Button
,
'Second child'
),
of:
find
.
widgetWithText
(
RawMaterial
Button
,
'Second child'
),
matching:
find
.
byType
(
DefaultTextStyle
),
)).
style
;
expect
(
textStyle
.
fontFamily
,
theme
.
textTheme
.
bodyText2
!.
fontFamily
);
...
...
@@ -256,7 +257,7 @@ void main() {
TextStyle
textStyle
;
textStyle
=
tester
.
widget
<
DefaultTextStyle
>(
find
.
descendant
(
of:
find
.
widgetWithText
(
Text
Button
,
'First child'
),
of:
find
.
widgetWithText
(
RawMaterial
Button
,
'First child'
),
matching:
find
.
byType
(
DefaultTextStyle
),
)).
style
;
expect
(
textStyle
.
textBaseline
,
TextBaseline
.
ideographic
);
...
...
@@ -264,7 +265,7 @@ void main() {
expect
(
textStyle
.
color
,
isNot
(
Colors
.
orange
));
textStyle
=
tester
.
widget
<
DefaultTextStyle
>(
find
.
descendant
(
of:
find
.
widgetWithText
(
Text
Button
,
'Second child'
),
of:
find
.
widgetWithText
(
RawMaterial
Button
,
'Second child'
),
matching:
find
.
byType
(
DefaultTextStyle
),
)).
style
;
expect
(
textStyle
.
textBaseline
,
TextBaseline
.
ideographic
);
...
...
@@ -289,13 +290,13 @@ void main() {
),
);
final
Rect
firstRect
=
tester
.
getRect
(
find
.
byType
(
Text
Button
).
at
(
0
));
final
Rect
firstRect
=
tester
.
getRect
(
find
.
byType
(
RawMaterial
Button
).
at
(
0
));
expect
(
firstRect
.
width
,
48.0
);
expect
(
firstRect
.
height
,
48.0
);
final
Rect
secondRect
=
tester
.
getRect
(
find
.
byType
(
Text
Button
).
at
(
1
));
final
Rect
secondRect
=
tester
.
getRect
(
find
.
byType
(
RawMaterial
Button
).
at
(
1
));
expect
(
secondRect
.
width
,
48.0
);
expect
(
secondRect
.
height
,
48.0
);
final
Rect
thirdRect
=
tester
.
getRect
(
find
.
byType
(
Text
Button
).
at
(
2
));
final
Rect
thirdRect
=
tester
.
getRect
(
find
.
byType
(
RawMaterial
Button
).
at
(
2
));
expect
(
thirdRect
.
width
,
48.0
);
expect
(
thirdRect
.
height
,
48.0
);
});
...
...
@@ -306,7 +307,6 @@ void main() {
Material
(
child:
boilerplate
(
child:
ToggleButtons
(
tapTargetSize:
MaterialTapTargetSize
.
shrinkWrap
,
constraints:
const
BoxConstraints
(
minWidth:
50.0
,
minHeight:
60.0
,
...
...
@@ -323,13 +323,13 @@ void main() {
),
);
Rect
firstRect
=
tester
.
getRect
(
find
.
byType
(
Text
Button
).
at
(
0
));
Rect
firstRect
=
tester
.
getRect
(
find
.
byType
(
RawMaterial
Button
).
at
(
0
));
expect
(
firstRect
.
width
,
50.0
);
expect
(
firstRect
.
height
,
60.0
);
Rect
secondRect
=
tester
.
getRect
(
find
.
byType
(
Text
Button
).
at
(
1
));
Rect
secondRect
=
tester
.
getRect
(
find
.
byType
(
RawMaterial
Button
).
at
(
1
));
expect
(
secondRect
.
width
,
50.0
);
expect
(
secondRect
.
height
,
60.0
);
Rect
thirdRect
=
tester
.
getRect
(
find
.
byType
(
Text
Button
).
at
(
2
));
Rect
thirdRect
=
tester
.
getRect
(
find
.
byType
(
RawMaterial
Button
).
at
(
2
));
expect
(
thirdRect
.
width
,
50.0
);
expect
(
thirdRect
.
height
,
60.0
);
...
...
@@ -338,7 +338,6 @@ void main() {
Material
(
child:
boilerplate
(
child:
ToggleButtons
(
tapTargetSize:
MaterialTapTargetSize
.
shrinkWrap
,
constraints:
const
BoxConstraints
(
maxWidth:
20.0
,
maxHeight:
10.0
,
...
...
@@ -355,13 +354,13 @@ void main() {
),
);
firstRect
=
tester
.
getRect
(
find
.
byType
(
Text
Button
).
at
(
0
));
firstRect
=
tester
.
getRect
(
find
.
byType
(
RawMaterial
Button
).
at
(
0
));
expect
(
firstRect
.
width
,
20.0
);
expect
(
firstRect
.
height
,
10.0
);
secondRect
=
tester
.
getRect
(
find
.
byType
(
Text
Button
).
at
(
1
));
secondRect
=
tester
.
getRect
(
find
.
byType
(
RawMaterial
Button
).
at
(
1
));
expect
(
secondRect
.
width
,
20.0
);
expect
(
secondRect
.
height
,
10.0
);
thirdRect
=
tester
.
getRect
(
find
.
byType
(
Text
Button
).
at
(
2
));
thirdRect
=
tester
.
getRect
(
find
.
byType
(
RawMaterial
Button
).
at
(
2
));
expect
(
thirdRect
.
width
,
20.0
);
expect
(
thirdRect
.
height
,
10.0
);
});
...
...
@@ -371,13 +370,13 @@ void main() {
(
WidgetTester
tester
)
async
{
TextStyle
buttonTextStyle
(
String
text
)
{
return
tester
.
widget
<
DefaultTextStyle
>(
find
.
descendant
(
of:
find
.
widgetWithText
(
Text
Button
,
text
),
of:
find
.
widgetWithText
(
RawMaterial
Button
,
text
),
matching:
find
.
byType
(
DefaultTextStyle
),
)).
style
;
}
IconTheme
iconTheme
(
IconData
icon
)
{
return
tester
.
widget
(
find
.
descendant
(
of:
find
.
widgetWithIcon
(
Text
Button
,
icon
),
of:
find
.
widgetWithIcon
(
RawMaterial
Button
,
icon
),
matching:
find
.
byType
(
IconTheme
),
));
}
...
...
@@ -469,13 +468,13 @@ void main() {
(
WidgetTester
tester
)
async
{
TextStyle
buttonTextStyle
(
String
text
)
{
return
tester
.
widget
<
DefaultTextStyle
>(
find
.
descendant
(
of:
find
.
widgetWithText
(
Text
Button
,
text
),
of:
find
.
widgetWithText
(
RawMaterial
Button
,
text
),
matching:
find
.
byType
(
DefaultTextStyle
),
)).
style
;
}
IconTheme
iconTheme
(
IconData
icon
)
{
return
tester
.
widget
(
find
.
descendant
(
of:
find
.
widgetWithIcon
(
Text
Button
,
icon
),
of:
find
.
widgetWithIcon
(
RawMaterial
Button
,
icon
),
matching:
find
.
byType
(
IconTheme
),
));
}
...
...
@@ -575,7 +574,7 @@ void main() {
);
final
Material
material
=
tester
.
widget
<
Material
>(
find
.
descendant
(
of:
find
.
byType
(
Text
Button
),
of:
find
.
byType
(
RawMaterial
Button
),
matching:
find
.
byType
(
Material
),
));
expect
(
...
...
@@ -604,7 +603,7 @@ void main() {
);
final
Material
material
=
tester
.
widget
<
Material
>(
find
.
descendant
(
of:
find
.
byType
(
Text
Button
),
of:
find
.
byType
(
RawMaterial
Button
),
matching:
find
.
byType
(
Material
),
));
expect
(
...
...
@@ -632,7 +631,7 @@ void main() {
);
final
Material
material
=
tester
.
widget
<
Material
>(
find
.
descendant
(
of:
find
.
byType
(
Text
Button
),
of:
find
.
byType
(
RawMaterial
Button
),
matching:
find
.
byType
(
Material
),
));
expect
(
...
...
@@ -662,7 +661,7 @@ void main() {
);
final
Material
material
=
tester
.
widget
<
Material
>(
find
.
descendant
(
of:
find
.
byType
(
Text
Button
),
of:
find
.
byType
(
RawMaterial
Button
),
matching:
find
.
byType
(
Material
),
));
expect
(
material
.
color
,
customFillColor
);
...
...
@@ -673,7 +672,7 @@ void main() {
Material
buttonColor
(
String
text
)
{
return
tester
.
widget
<
Material
>(
find
.
descendant
(
of:
find
.
byType
(
Text
Button
),
of:
find
.
byType
(
RawMaterial
Button
),
matching:
find
.
widgetWithText
(
Material
,
text
),
),
);
...
...
@@ -728,7 +727,7 @@ void main() {
Material
buttonColor
(
String
text
)
{
return
tester
.
widget
<
Material
>(
find
.
descendant
(
of:
find
.
byType
(
Text
Button
),
of:
find
.
byType
(
RawMaterial
Button
),
matching:
find
.
widgetWithText
(
Material
,
text
),
),
);
...
...
@@ -1616,7 +1615,7 @@ void main() {
final
Key
key1
=
UniqueKey
();
await
tester
.
pumpWidget
(
buildFrame
(
MaterialTapTargetSize
.
padded
,
key1
));
expect
(
tester
.
getSize
(
find
.
byKey
(
key1
)),
const
Size
(
228.0
,
50
.0
));
expect
(
tester
.
getSize
(
find
.
byKey
(
key1
)),
const
Size
(
228.0
,
48
.0
));
final
Key
key2
=
UniqueKey
();
await
tester
.
pumpWidget
(
buildFrame
(
MaterialTapTargetSize
.
shrinkWrap
,
key2
));
...
...
@@ -1645,7 +1644,7 @@ void main() {
final
Key
key1
=
UniqueKey
();
await
tester
.
pumpWidget
(
buildFrame
(
MaterialTapTargetSize
.
padded
,
key1
));
expect
(
tester
.
getSize
(
find
.
byKey
(
key1
)),
const
Size
(
228.0
,
50
.0
));
expect
(
tester
.
getSize
(
find
.
byKey
(
key1
)),
const
Size
(
228.0
,
48
.0
));
final
Key
key2
=
UniqueKey
();
await
tester
.
pumpWidget
(
buildFrame
(
MaterialTapTargetSize
.
shrinkWrap
,
key2
));
...
...
@@ -1675,7 +1674,7 @@ void main() {
final
Key
key1
=
UniqueKey
();
await
tester
.
pumpWidget
(
buildFrame
(
MaterialTapTargetSize
.
padded
,
key1
));
expect
(
tester
.
getSize
(
find
.
byKey
(
key1
)),
const
Size
(
50.0
,
148
.0
));
expect
(
tester
.
getSize
(
find
.
byKey
(
key1
)),
const
Size
(
48.0
,
100
.0
));
final
Key
key2
=
UniqueKey
();
await
tester
.
pumpWidget
(
buildFrame
(
MaterialTapTargetSize
.
shrinkWrap
,
key2
));
...
...
@@ -1911,31 +1910,4 @@ void main() {
await
hoverGesture
.
removePointer
();
});
testWidgets
(
'Toggle buttons height matches MaterialTapTargetSize.padded height'
,
(
WidgetTester
tester
)
async
{
// Regression test for https://github.com/flutter/flutter/issues/97302
await
tester
.
pumpWidget
(
Material
(
child:
boilerplate
(
child:
ToggleButtons
(
tapTargetSize:
MaterialTapTargetSize
.
padded
,
isSelected:
const
<
bool
>[
false
,
false
,
false
],
onPressed:
(
int
index
)
{},
children:
const
<
Widget
>[
Icon
(
Icons
.
check
),
Icon
(
Icons
.
access_alarm
),
Icon
(
Icons
.
cake
),
],
),
),
),
);
final
Rect
firstRect
=
tester
.
getRect
(
find
.
byType
(
TextButton
).
at
(
0
));
expect
(
firstRect
.
height
,
48.0
);
final
Rect
secondRect
=
tester
.
getRect
(
find
.
byType
(
TextButton
).
at
(
1
));
expect
(
secondRect
.
height
,
48.0
);
final
Rect
thirdRect
=
tester
.
getRect
(
find
.
byType
(
TextButton
).
at
(
2
));
expect
(
thirdRect
.
height
,
48.0
);
});
}
packages/flutter/test/material/toggle_buttons_theme_test.dart
View file @
f5be639e
...
...
@@ -142,7 +142,7 @@ void main() {
TextStyle
textStyle
;
textStyle
=
tester
.
widget
<
DefaultTextStyle
>(
find
.
descendant
(
of:
find
.
widgetWithText
(
Text
Button
,
'First child'
),
of:
find
.
widgetWithText
(
RawMaterial
Button
,
'First child'
),
matching:
find
.
byType
(
DefaultTextStyle
),
)).
style
;
expect
(
textStyle
.
textBaseline
,
TextBaseline
.
ideographic
);
...
...
@@ -150,7 +150,7 @@ void main() {
expect
(
textStyle
.
color
,
isNot
(
Colors
.
orange
));
textStyle
=
tester
.
widget
<
DefaultTextStyle
>(
find
.
descendant
(
of:
find
.
widgetWithText
(
Text
Button
,
'Second child'
),
of:
find
.
widgetWithText
(
RawMaterial
Button
,
'Second child'
),
matching:
find
.
byType
(
DefaultTextStyle
),
)).
style
;
expect
(
textStyle
.
textBaseline
,
TextBaseline
.
ideographic
);
...
...
@@ -171,7 +171,6 @@ void main() {
),
),
child:
ToggleButtons
(
tapTargetSize:
MaterialTapTargetSize
.
shrinkWrap
,
isSelected:
const
<
bool
>[
false
,
false
,
false
],
onPressed:
(
int
index
)
{},
children:
const
<
Widget
>[
...
...
@@ -185,13 +184,13 @@ void main() {
),
);
Rect
firstRect
=
tester
.
getRect
(
find
.
byType
(
Text
Button
).
at
(
0
));
Rect
firstRect
=
tester
.
getRect
(
find
.
byType
(
RawMaterial
Button
).
at
(
0
));
expect
(
firstRect
.
width
,
50.0
);
expect
(
firstRect
.
height
,
60.0
);
Rect
secondRect
=
tester
.
getRect
(
find
.
byType
(
Text
Button
).
at
(
1
));
Rect
secondRect
=
tester
.
getRect
(
find
.
byType
(
RawMaterial
Button
).
at
(
1
));
expect
(
secondRect
.
width
,
50.0
);
expect
(
secondRect
.
height
,
60.0
);
Rect
thirdRect
=
tester
.
getRect
(
find
.
byType
(
Text
Button
).
at
(
2
));
Rect
thirdRect
=
tester
.
getRect
(
find
.
byType
(
RawMaterial
Button
).
at
(
2
));
expect
(
thirdRect
.
width
,
50.0
);
expect
(
thirdRect
.
height
,
60.0
);
...
...
@@ -207,7 +206,6 @@ void main() {
),
),
child:
ToggleButtons
(
tapTargetSize:
MaterialTapTargetSize
.
shrinkWrap
,
isSelected:
const
<
bool
>[
false
,
false
,
false
],
onPressed:
(
int
index
)
{},
children:
const
<
Widget
>[
...
...
@@ -221,13 +219,13 @@ void main() {
),
);
firstRect
=
tester
.
getRect
(
find
.
byType
(
Text
Button
).
at
(
0
));
firstRect
=
tester
.
getRect
(
find
.
byType
(
RawMaterial
Button
).
at
(
0
));
expect
(
firstRect
.
width
,
20.0
);
expect
(
firstRect
.
height
,
10.0
);
secondRect
=
tester
.
getRect
(
find
.
byType
(
Text
Button
).
at
(
1
));
secondRect
=
tester
.
getRect
(
find
.
byType
(
RawMaterial
Button
).
at
(
1
));
expect
(
secondRect
.
width
,
20.0
);
expect
(
secondRect
.
height
,
10.0
);
thirdRect
=
tester
.
getRect
(
find
.
byType
(
Text
Button
).
at
(
2
));
thirdRect
=
tester
.
getRect
(
find
.
byType
(
RawMaterial
Button
).
at
(
2
));
expect
(
thirdRect
.
width
,
20.0
);
expect
(
thirdRect
.
height
,
10.0
);
});
...
...
@@ -237,13 +235,13 @@ void main() {
(
WidgetTester
tester
)
async
{
TextStyle
buttonTextStyle
(
String
text
)
{
return
tester
.
widget
<
DefaultTextStyle
>(
find
.
descendant
(
of:
find
.
widgetWithText
(
Text
Button
,
text
),
of:
find
.
widgetWithText
(
RawMaterial
Button
,
text
),
matching:
find
.
byType
(
DefaultTextStyle
),
)).
style
;
}
IconTheme
iconTheme
(
IconData
icon
)
{
return
tester
.
widget
(
find
.
descendant
(
of:
find
.
widgetWithIcon
(
Text
Button
,
icon
),
of:
find
.
widgetWithIcon
(
RawMaterial
Button
,
icon
),
matching:
find
.
byType
(
IconTheme
),
));
}
...
...
@@ -358,7 +356,7 @@ void main() {
);
final
Material
material
=
tester
.
widget
<
Material
>(
find
.
descendant
(
of:
find
.
byType
(
Text
Button
),
of:
find
.
byType
(
RawMaterial
Button
),
matching:
find
.
byType
(
Material
),
));
expect
(
material
.
color
,
customFillColor
);
...
...
@@ -369,7 +367,7 @@ void main() {
Material
buttonColor
(
String
text
)
{
return
tester
.
widget
<
Material
>(
find
.
descendant
(
of:
find
.
byType
(
Text
Button
),
of:
find
.
byType
(
RawMaterial
Button
),
matching:
find
.
widgetWithText
(
Material
,
text
),
),
);
...
...
@@ -478,6 +476,7 @@ void main() {
inkFeatures
,
paints
..
circle
(
color:
splashColor
)
..
rect
(
color:
highlightColor
),
);
await
touchGesture
.
up
();
...
...
@@ -508,6 +507,7 @@ void main() {
await
hoverGesture
.
removePointer
();
});
testWidgets
(
'Theme border width and border colors for enabled, selected and disabled states'
,
(
WidgetTester
tester
)
async
{
...
...
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