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
60de2deb
Unverified
Commit
60de2deb
authored
Oct 25, 2018
by
jslavitz
Committed by
GitHub
Oct 25, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adds custom control builder functionality to Stepper (#23310)
* Adds test and builder
parent
bc56a7a6
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
141 additions
and
0 deletions
+141
-0
stepper.dart
packages/flutter/lib/src/material/stepper.dart
+51
-0
framework.dart
packages/flutter/lib/src/widgets/framework.dart
+5
-0
stepper_test.dart
packages/flutter/test/material/stepper_test.dart
+85
-0
No files found.
packages/flutter/lib/src/material/stepper.dart
View file @
60de2deb
...
@@ -140,6 +140,7 @@ class Stepper extends StatefulWidget {
...
@@ -140,6 +140,7 @@ class Stepper extends StatefulWidget {
this
.
onStepTapped
,
this
.
onStepTapped
,
this
.
onStepContinue
,
this
.
onStepContinue
,
this
.
onStepCancel
,
this
.
onStepCancel
,
this
.
controlsBuilder
,
})
:
assert
(
steps
!=
null
),
})
:
assert
(
steps
!=
null
),
assert
(
type
!=
null
),
assert
(
type
!=
null
),
assert
(
currentStep
!=
null
),
assert
(
currentStep
!=
null
),
...
@@ -174,6 +175,53 @@ class Stepper extends StatefulWidget {
...
@@ -174,6 +175,53 @@ class Stepper extends StatefulWidget {
/// If null, the 'cancel' button will be disabled.
/// If null, the 'cancel' button will be disabled.
final
VoidCallback
onStepCancel
;
final
VoidCallback
onStepCancel
;
/// The callback for creating custom controls.
///
/// If null, the default controls from the current theme will be used.
///
/// This callback which takes in a context and two functions,[onStepContinue]
/// and [onStepCancel]. These can be used to control the stepper.
///
/// ## Sample Code:
/// Creates a stepper control with custom buttons.
///
/// ```dart
/// Stepper(
/// controlsBuilder:
/// (BuildContext context, {VoidCallback onStepContinue, VoidCallback onStepCancel}) {
/// return Row(
/// children: <Widget>[
/// FlatButton(
/// onPressed: onStepContinue,
/// child: const Text('My Awesome Continue Message!'),
/// ),
/// FlatButton(
/// onPressed: onStepCancel,
/// child: const Text('My Awesome Cancel Message!'),
/// ),
/// ],
/// ),
/// },
/// steps: const <Step>[
/// Step(
/// title: Text('A'),
/// content: SizedBox(
/// width: 100.0,
/// height: 100.0,
/// ),
/// ),
/// Step(
/// title: Text('B'),
/// content: SizedBox(
/// width: 100.0,
/// height: 100.0,
/// ),
/// ),
/// ],
/// )
/// ```
final
ControlsWidgetBuilder
controlsBuilder
;
@override
@override
_StepperState
createState
()
=>
_StepperState
();
_StepperState
createState
()
=>
_StepperState
();
}
}
...
@@ -327,6 +375,9 @@ class _StepperState extends State<Stepper> with TickerProviderStateMixin {
...
@@ -327,6 +375,9 @@ class _StepperState extends State<Stepper> with TickerProviderStateMixin {
}
}
Widget
_buildVerticalControls
()
{
Widget
_buildVerticalControls
()
{
if
(
widget
.
controlsBuilder
!=
null
)
return
widget
.
controlsBuilder
(
context
,
onStepContinue:
widget
.
onStepContinue
,
onStepCancel:
widget
.
onStepCancel
);
Color
cancelColor
;
Color
cancelColor
;
switch
(
Theme
.
of
(
context
).
brightness
)
{
switch
(
Theme
.
of
(
context
).
brightness
)
{
...
...
packages/flutter/lib/src/widgets/framework.dart
View file @
60de2deb
...
@@ -3632,6 +3632,11 @@ typedef IndexedWidgetBuilder = Widget Function(BuildContext context, int index);
...
@@ -3632,6 +3632,11 @@ typedef IndexedWidgetBuilder = Widget Function(BuildContext context, int index);
/// [MaterialApp.builder].
/// [MaterialApp.builder].
typedef
TransitionBuilder
=
Widget
Function
(
BuildContext
context
,
Widget
child
);
typedef
TransitionBuilder
=
Widget
Function
(
BuildContext
context
,
Widget
child
);
/// A Signiture for a function that creates a widget given [onStepContinue] and [onStepCancel].
///
/// Used by [Stepper.builder].
typedef
ControlsWidgetBuilder
=
Widget
Function
(
BuildContext
context
,
{
VoidCallback
onStepContinue
,
VoidCallback
onStepCancel
});
/// An [Element] that composes other [Element]s.
/// An [Element] that composes other [Element]s.
///
///
/// Rather than creating a [RenderObject] directly, a [ComponentElement] creates
/// Rather than creating a [RenderObject] directly, a [ComponentElement] creates
...
...
packages/flutter/test/material/stepper_test.dart
View file @
60de2deb
...
@@ -368,6 +368,91 @@ void main() {
...
@@ -368,6 +368,91 @@ void main() {
expect
(
find
.
text
(
'2'
),
findsOneWidget
);
expect
(
find
.
text
(
'2'
),
findsOneWidget
);
});
});
testWidgets
(
'Stepper custom controls test'
,
(
WidgetTester
tester
)
async
{
bool
continuePressed
=
false
;
void
setContinue
()
{
continuePressed
=
true
;
}
bool
canceledPressed
=
false
;
void
setCanceled
()
{
canceledPressed
=
true
;
}
final
ControlsWidgetBuilder
builder
=
(
BuildContext
context
,
{
VoidCallback
onStepContinue
,
VoidCallback
onStepCancel
})
{
return
Container
(
margin:
const
EdgeInsets
.
only
(
top:
16.0
),
child:
ConstrainedBox
(
constraints:
const
BoxConstraints
.
tightFor
(
height:
48.0
),
child:
Row
(
children:
<
Widget
>[
FlatButton
(
onPressed:
onStepContinue
,
color:
Colors
.
blue
,
textColor:
Colors
.
white
,
textTheme:
ButtonTextTheme
.
normal
,
child:
const
Text
(
'Let us continue!'
),
),
Container
(
margin:
const
EdgeInsetsDirectional
.
only
(
start:
8.0
),
child:
FlatButton
(
onPressed:
onStepCancel
,
textColor:
Colors
.
red
,
textTheme:
ButtonTextTheme
.
normal
,
child:
const
Text
(
'Cancel This!'
),
),
),
],
),
),
);
};
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Center
(
child:
Material
(
child:
Stepper
(
controlsBuilder:
builder
,
onStepCancel:
setCanceled
,
onStepContinue:
setContinue
,
steps:
const
<
Step
>[
Step
(
title:
Text
(
'A'
),
state:
StepState
.
complete
,
content:
SizedBox
(
width:
100.0
,
height:
100.0
,
),
),
Step
(
title:
Text
(
'B'
),
content:
SizedBox
(
width:
100.0
,
height:
100.0
,
),
),
],
),
),
),
),
);
// 2 because stepper creates a set of controls for each step
expect
(
find
.
text
(
'Let us continue!'
),
findsNWidgets
(
2
));
expect
(
find
.
text
(
'Cancel This!'
),
findsNWidgets
(
2
));
await
tester
.
tap
(
find
.
text
(
'Cancel This!'
).
first
);
await
tester
.
pumpAndSettle
();
await
tester
.
tap
(
find
.
text
(
'Let us continue!'
).
first
);
await
tester
.
pumpAndSettle
();
expect
(
canceledPressed
,
isTrue
);
expect
(
continuePressed
,
isTrue
);
});
testWidgets
(
'Stepper error test'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'Stepper error test'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
MaterialApp
(
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