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
df8d8194
Unverified
Commit
df8d8194
authored
Apr 17, 2023
by
Mubarak Bakarman
Committed by
GitHub
Apr 17, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Customize color and thickness of connected lines in Stepper.dart (#122485)
parent
53f31c7c
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
117 additions
and
11 deletions
+117
-11
stepper.dart
packages/flutter/lib/src/material/stepper.dart
+48
-11
stepper_test.dart
packages/flutter/test/material/stepper_test.dart
+69
-0
No files found.
packages/flutter/lib/src/material/stepper.dart
View file @
df8d8194
...
...
@@ -211,6 +211,8 @@ class Stepper extends StatefulWidget {
this
.
controlsBuilder
,
this
.
elevation
,
this
.
margin
,
this
.
connectorColor
,
this
.
connectorThickness
,
this
.
stepIconBuilder
,
})
:
assert
(
0
<=
currentStep
&&
currentStep
<
steps
.
length
);
...
...
@@ -311,6 +313,19 @@ class Stepper extends StatefulWidget {
/// Custom margin on vertical stepper.
final
EdgeInsetsGeometry
?
margin
;
/// Customize connected lines colors.
///
/// Resolves in the following states:
/// * [MaterialState.selected].
/// * [MaterialState.disabled].
///
/// If not set then the widget will use default colors, primary for selected state
/// and grey.shade400 for disabled state.
final
MaterialStateProperty
<
Color
>?
connectorColor
;
/// The thickness of the connecting lines.
final
double
?
connectorThickness
;
/// Callback for creating custom icons for the [steps].
///
/// When overriding icon for [StepState.error], please return
...
...
@@ -375,11 +390,23 @@ class _StepperState extends State<Stepper> with TickerProviderStateMixin {
return
false
;
}
Widget
_buildLine
(
bool
visible
)
{
Color
_connectorColor
(
bool
isActive
)
{
final
ColorScheme
colorScheme
=
Theme
.
of
(
context
).
colorScheme
;
final
Set
<
MaterialState
>
states
=
<
MaterialState
>{
if
(
isActive
)
MaterialState
.
selected
else
MaterialState
.
disabled
,
};
final
Color
?
resolvedConnectorColor
=
widget
.
connectorColor
?.
resolve
(
states
);
if
(
resolvedConnectorColor
!=
null
)
{
return
resolvedConnectorColor
;
}
return
isActive
?
colorScheme
.
primary
:
Colors
.
grey
.
shade400
;
}
Widget
_buildLine
(
bool
visible
,
bool
isActive
)
{
return
Container
(
width:
visible
?
1.0
:
0.0
,
width:
visible
?
widget
.
connectorThickness
??
1.0
:
0.0
,
height:
16.0
,
color:
Colors
.
grey
.
shade400
,
color:
_connectorColor
(
isActive
)
,
);
}
...
...
@@ -415,11 +442,19 @@ class _StepperState extends State<Stepper> with TickerProviderStateMixin {
}
Color
_circleColor
(
int
index
)
{
final
bool
isActive
=
widget
.
steps
[
index
].
isActive
;
final
ColorScheme
colorScheme
=
Theme
.
of
(
context
).
colorScheme
;
final
Set
<
MaterialState
>
states
=
<
MaterialState
>{
if
(
isActive
)
MaterialState
.
selected
else
MaterialState
.
disabled
,
};
final
Color
?
resolvedConnectorColor
=
widget
.
connectorColor
?.
resolve
(
states
);
if
(
resolvedConnectorColor
!=
null
)
{
return
resolvedConnectorColor
;
}
if
(!
_isDark
())
{
return
widget
.
steps
[
index
].
isActive
?
colorScheme
.
primary
:
colorScheme
.
onSurface
.
withOpacity
(
0.38
);
return
isActive
?
colorScheme
.
primary
:
colorScheme
.
onSurface
.
withOpacity
(
0.38
);
}
else
{
return
widget
.
steps
[
index
].
isActive
?
colorScheme
.
secondary
:
colorScheme
.
background
;
return
isActive
?
colorScheme
.
secondary
:
colorScheme
.
background
;
}
}
...
...
@@ -659,6 +694,7 @@ class _StepperState extends State<Stepper> with TickerProviderStateMixin {
}
Widget
_buildVerticalHeader
(
int
index
)
{
final
bool
isActive
=
widget
.
steps
[
index
].
isActive
;
return
Container
(
margin:
const
EdgeInsets
.
symmetric
(
horizontal:
24.0
),
child:
Row
(
...
...
@@ -667,9 +703,9 @@ class _StepperState extends State<Stepper> with TickerProviderStateMixin {
children:
<
Widget
>[
// Line parts are always added in order for the ink splash to
// flood the tips of the connector lines.
_buildLine
(!
_isFirst
(
index
)),
_buildLine
(!
_isFirst
(
index
)
,
isActive
),
_buildIcon
(
index
),
_buildLine
(!
_isLast
(
index
)),
_buildLine
(!
_isLast
(
index
)
,
isActive
),
],
),
Expanded
(
...
...
@@ -694,9 +730,9 @@ class _StepperState extends State<Stepper> with TickerProviderStateMixin {
width:
24.0
,
child:
Center
(
child:
SizedBox
(
width:
_isLast
(
index
)
?
0.0
:
1.0
,
width:
widget
.
connectorThickness
??
1.0
,
child:
Container
(
color:
Colors
.
grey
.
shade400
,
color:
_connectorColor
(
widget
.
steps
[
index
].
isActive
)
,
),
),
),
...
...
@@ -789,9 +825,10 @@ class _StepperState extends State<Stepper> with TickerProviderStateMixin {
if
(!
_isLast
(
i
))
Expanded
(
child:
Container
(
key:
Key
(
'line
$i
'
),
margin:
const
EdgeInsets
.
symmetric
(
horizontal:
8.0
),
height:
1.0
,
color:
Colors
.
grey
.
shade400
,
height:
widget
.
connectorThickness
??
1.0
,
color:
_connectorColor
(
widget
.
steps
[
i
+
1
].
isActive
)
,
),
),
],
...
...
packages/flutter/test/material/stepper_test.dart
View file @
df8d8194
...
...
@@ -1260,6 +1260,75 @@ testWidgets('Stepper custom indexed controls test', (WidgetTester tester) async
expect
(
bodyMediumStyle
,
nextLabelTextWidget
.
style
);
});
testWidgets
(
'Stepper Connector Style'
,
(
WidgetTester
tester
)
async
{
const
Color
selectedColor
=
Colors
.
black
;
const
Color
disabledColor
=
Colors
.
white
;
int
index
=
0
;
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Scaffold
(
body:
Center
(
child:
StatefulBuilder
(
builder:
(
BuildContext
context
,
StateSetter
setState
)
{
return
Stepper
(
type:
StepperType
.
horizontal
,
connectorColor:
MaterialStateProperty
.
resolveWith
<
Color
>((
Set
<
MaterialState
>
states
)
=>
states
.
contains
(
MaterialState
.
selected
)
?
selectedColor
:
disabledColor
),
onStepTapped:
(
int
i
)
=>
setState
(()
=>
index
=
i
),
currentStep:
index
,
steps:
<
Step
>[
Step
(
isActive:
index
>=
0
,
title:
const
Text
(
'step1'
),
content:
const
Text
(
'step1 content'
),
),
Step
(
isActive:
index
>=
1
,
title:
const
Text
(
'step2'
),
content:
const
Text
(
'step2 content'
),
),
],
);
},
),
),
),
)
);
Color
?
circleColor
(
String
circleText
)
=>
(
tester
.
widget
<
AnimatedContainer
>(
find
.
widgetWithText
(
AnimatedContainer
,
circleText
),
).
decoration
as
BoxDecoration
?)?.
color
;
Color
?
lineColor
(
String
keyStep
)
=>
tester
.
widget
<
Container
>(
find
.
byKey
(
Key
(
keyStep
))).
color
;
// Step 1
// check if I'm in step 1
expect
(
find
.
text
(
'step1 content'
),
findsOneWidget
);
expect
(
find
.
text
(
'step2 content'
),
findsNothing
);
expect
(
circleColor
(
'1'
),
selectedColor
);
expect
(
circleColor
(
'2'
),
disabledColor
);
// in two steps case there will be single line
expect
(
lineColor
(
'line0'
),
disabledColor
);
// now hitting step two
await
tester
.
tap
(
find
.
text
(
'step2'
));
await
tester
.
pumpAndSettle
();
// check if I'm in step 1
expect
(
find
.
text
(
'step1 content'
),
findsNothing
);
expect
(
find
.
text
(
'step2 content'
),
findsOneWidget
);
expect
(
circleColor
(
'1'
),
selectedColor
);
expect
(
circleColor
(
'2'
),
selectedColor
);
expect
(
lineColor
(
'line0'
),
selectedColor
);
});
testWidgets
(
'Stepper stepIconBuilder test'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
MaterialApp
(
...
...
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