Last changes not published
This commit is contained in:
parent
ac65ccf990
commit
21ec08303a
43 changed files with 607 additions and 613 deletions
|
|
@ -3,7 +3,6 @@
|
|||
// found in the LICENSE file.
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
||||
// TODO(dragostis): Missing functionality:
|
||||
// * mobile horizontal mode with adding/removing steps
|
||||
// * alternative labeling
|
||||
|
|
@ -53,7 +52,8 @@ const Color _kCircleActiveDark = Colors.black87;
|
|||
const Color _kDisabledLight = Colors.black38;
|
||||
const Color _kDisabledDark = Colors.white30;
|
||||
const double _kCustomStepSize = 24.0;
|
||||
const double _kTriangleHeight = _kCustomStepSize * 0.866025; // Triangle height. sqrt(3.0) / 2.0
|
||||
const double _kTriangleHeight =
|
||||
_kCustomStepSize * 0.866025; // Triangle height. sqrt(3.0) / 2.0
|
||||
|
||||
/// A material step used in [CustomStepper]. The step can have a title and subtitle,
|
||||
/// an icon within its circle, some content and a state that governs its
|
||||
|
|
@ -75,9 +75,9 @@ class CustomStep {
|
|||
@required this.content,
|
||||
this.state: CustomStepState.indexed,
|
||||
this.isActive: false,
|
||||
}) : assert(title != null),
|
||||
assert(content != null),
|
||||
assert(state != null);
|
||||
}) : assert(title != null),
|
||||
assert(content != null),
|
||||
assert(state != null);
|
||||
|
||||
/// The title of the step that typically describes it.
|
||||
final Widget title;
|
||||
|
|
@ -130,11 +130,11 @@ class CustomStepper extends StatefulWidget {
|
|||
this.onCustomStepTapped,
|
||||
this.onCustomStepContinue,
|
||||
this.onCustomStepCancel,
|
||||
}) : assert(steps != null),
|
||||
assert(type != null),
|
||||
assert(currentCustomStep != null),
|
||||
assert(0 <= currentCustomStep && currentCustomStep < steps.length),
|
||||
super(key: key);
|
||||
}) : assert(steps != null),
|
||||
assert(type != null),
|
||||
assert(currentCustomStep != null),
|
||||
assert(0 <= currentCustomStep && currentCustomStep < steps.length),
|
||||
super(key: key);
|
||||
|
||||
/// The steps of the stepper whose titles, subtitles, icons always get shown.
|
||||
///
|
||||
|
|
@ -177,7 +177,7 @@ class _CustomStepperState extends State<CustomStepper> {
|
|||
super.initState();
|
||||
_keys = new List<GlobalKey>.generate(
|
||||
widget.steps.length,
|
||||
(int i) => new GlobalKey(),
|
||||
(int i) => new GlobalKey(),
|
||||
);
|
||||
|
||||
for (int i = 0; i < widget.steps.length; i += 1)
|
||||
|
|
@ -218,7 +218,8 @@ class _CustomStepperState extends State<CustomStepper> {
|
|||
}
|
||||
|
||||
Widget _buildCircleChild(int index, bool oldState) {
|
||||
final CustomStepState state = oldState ? _oldStates[index] : widget.steps[index].state;
|
||||
final CustomStepState state =
|
||||
oldState ? _oldStates[index] : widget.steps[index].state;
|
||||
final bool isDarkActive = _isDark() && widget.steps[index].isActive;
|
||||
assert(state != null);
|
||||
switch (state) {
|
||||
|
|
@ -226,7 +227,9 @@ class _CustomStepperState extends State<CustomStepper> {
|
|||
case CustomStepState.disabled:
|
||||
return new Text(
|
||||
'${index + 1}',
|
||||
style: isDarkActive ? _kCustomStepStyle.copyWith(color: Colors.black87) : _kCustomStepStyle,
|
||||
style: isDarkActive
|
||||
? _kCustomStepStyle.copyWith(color: Colors.black87)
|
||||
: _kCustomStepStyle,
|
||||
);
|
||||
case CustomStepState.editing:
|
||||
return new Icon(
|
||||
|
|
@ -247,9 +250,13 @@ class _CustomStepperState extends State<CustomStepper> {
|
|||
Color _circleColor(int index) {
|
||||
final ThemeData themeData = Theme.of(context);
|
||||
if (!_isDark()) {
|
||||
return widget.steps[index].isActive ? themeData.primaryColor : Colors.black38;
|
||||
return widget.steps[index].isActive
|
||||
? themeData.primaryColor
|
||||
: Colors.black38;
|
||||
} else {
|
||||
return widget.steps[index].isActive ? themeData.accentColor : themeData.backgroundColor;
|
||||
return widget.steps[index].isActive
|
||||
? themeData.accentColor
|
||||
: themeData.backgroundColor;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -266,7 +273,8 @@ class _CustomStepperState extends State<CustomStepper> {
|
|||
shape: BoxShape.circle,
|
||||
),
|
||||
child: new Center(
|
||||
child: _buildCircleChild(index, oldState && widget.steps[index].state == CustomStepState.error),
|
||||
child: _buildCircleChild(index,
|
||||
oldState && widget.steps[index].state == CustomStepState.error),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
@ -280,14 +288,19 @@ class _CustomStepperState extends State<CustomStepper> {
|
|||
child: new Center(
|
||||
child: new SizedBox(
|
||||
width: _kCustomStepSize,
|
||||
height: _kTriangleHeight, // Height of 24dp-long-sided equilateral triangle.
|
||||
height:
|
||||
_kTriangleHeight, // Height of 24dp-long-sided equilateral triangle.
|
||||
child: new CustomPaint(
|
||||
painter: new _TrianglePainter(
|
||||
color: _isDark() ? _kErrorDark : _kErrorLight,
|
||||
),
|
||||
child: new Align(
|
||||
alignment: const Alignment(0.0, 0.8), // 0.8 looks better than the geometrical 0.33.
|
||||
child: _buildCircleChild(index, oldState && widget.steps[index].state != CustomStepState.error),
|
||||
alignment: const Alignment(
|
||||
0.0, 0.8), // 0.8 looks better than the geometrical 0.33.
|
||||
child: _buildCircleChild(
|
||||
index,
|
||||
oldState &&
|
||||
widget.steps[index].state != CustomStepState.error),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -303,7 +316,9 @@ class _CustomStepperState extends State<CustomStepper> {
|
|||
firstCurve: const Interval(0.0, 0.6, curve: Curves.fastOutSlowIn),
|
||||
secondCurve: const Interval(0.4, 1.0, curve: Curves.fastOutSlowIn),
|
||||
sizeCurve: Curves.fastOutSlowIn,
|
||||
crossFadeState: widget.steps[index].state == CustomStepState.error ? CrossFadeState.showSecond : CrossFadeState.showFirst,
|
||||
crossFadeState: widget.steps[index].state == CustomStepState.error
|
||||
? CrossFadeState.showSecond
|
||||
: CrossFadeState.showFirst,
|
||||
duration: kThemeAnimationDuration,
|
||||
);
|
||||
} else {
|
||||
|
|
@ -328,8 +343,9 @@ class _CustomStepperState extends State<CustomStepper> {
|
|||
|
||||
assert(cancelColor != null);
|
||||
|
||||
final ThemeData themeData = Theme.of(context);
|
||||
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
|
||||
// final ThemeData themeData = Theme.of(context);
|
||||
// final MaterialLocalizations localizations =
|
||||
// MaterialLocalizations.of(context);
|
||||
|
||||
return new Container(
|
||||
margin: const EdgeInsets.only(top: 16.0),
|
||||
|
|
@ -368,15 +384,13 @@ class _CustomStepperState extends State<CustomStepper> {
|
|||
case CustomStepState.indexed:
|
||||
case CustomStepState.editing:
|
||||
case CustomStepState.complete:
|
||||
return textTheme.body2;
|
||||
return textTheme.bodyText1;
|
||||
case CustomStepState.disabled:
|
||||
return textTheme.body2.copyWith(
|
||||
color: _isDark() ? _kDisabledDark : _kDisabledLight
|
||||
);
|
||||
return textTheme.bodyText1
|
||||
.copyWith(color: _isDark() ? _kDisabledDark : _kDisabledLight);
|
||||
case CustomStepState.error:
|
||||
return textTheme.body2.copyWith(
|
||||
color: _isDark() ? _kErrorDark : _kErrorLight
|
||||
);
|
||||
return textTheme.bodyText1
|
||||
.copyWith(color: _isDark() ? _kErrorDark : _kErrorLight);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -392,13 +406,11 @@ class _CustomStepperState extends State<CustomStepper> {
|
|||
case CustomStepState.complete:
|
||||
return textTheme.caption;
|
||||
case CustomStepState.disabled:
|
||||
return textTheme.caption.copyWith(
|
||||
color: _isDark() ? _kDisabledDark : _kDisabledLight
|
||||
);
|
||||
return textTheme.caption
|
||||
.copyWith(color: _isDark() ? _kDisabledDark : _kDisabledLight);
|
||||
case CustomStepState.error:
|
||||
return textTheme.caption.copyWith(
|
||||
color: _isDark() ? _kErrorDark : _kErrorLight
|
||||
);
|
||||
return textTheme.caption
|
||||
.copyWith(color: _isDark() ? _kErrorDark : _kErrorLight);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -427,33 +439,26 @@ class _CustomStepperState extends State<CustomStepper> {
|
|||
);
|
||||
|
||||
return new Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: children
|
||||
);
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: children);
|
||||
}
|
||||
|
||||
Widget _buildVerticalHeader(int index) {
|
||||
return new Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 24.0),
|
||||
child: new Row(
|
||||
children: <Widget>[
|
||||
new Column(
|
||||
children: <Widget>[
|
||||
// Line parts are always added in order for the ink splash to
|
||||
// flood the tips of the connector lines.
|
||||
_buildLine(!_isFirst(index)),
|
||||
_buildIcon(index),
|
||||
_buildLine(!_isLast(index)),
|
||||
]
|
||||
),
|
||||
margin: const EdgeInsets.symmetric(horizontal: 24.0),
|
||||
child: new Row(children: <Widget>[
|
||||
new Column(children: <Widget>[
|
||||
// Line parts are always added in order for the ink splash to
|
||||
// flood the tips of the connector lines.
|
||||
_buildLine(!_isFirst(index)),
|
||||
_buildIcon(index),
|
||||
_buildLine(!_isLast(index)),
|
||||
]),
|
||||
new Container(
|
||||
margin: const EdgeInsetsDirectional.only(start: 12.0),
|
||||
child: _buildHeaderText(index)
|
||||
)
|
||||
]
|
||||
)
|
||||
);
|
||||
margin: const EdgeInsetsDirectional.only(start: 12.0),
|
||||
child: _buildHeaderText(index))
|
||||
]));
|
||||
}
|
||||
|
||||
Widget _buildVerticalBody(int index) {
|
||||
|
|
@ -493,7 +498,9 @@ class _CustomStepperState extends State<CustomStepper> {
|
|||
firstCurve: const Interval(0.0, 0.6, curve: Curves.fastOutSlowIn),
|
||||
secondCurve: const Interval(0.4, 1.0, curve: Curves.fastOutSlowIn),
|
||||
sizeCurve: Curves.fastOutSlowIn,
|
||||
crossFadeState: _isCurrent(index) ? CrossFadeState.showSecond : CrossFadeState.showFirst,
|
||||
crossFadeState: _isCurrent(index)
|
||||
? CrossFadeState.showSecond
|
||||
: CrossFadeState.showFirst,
|
||||
duration: kThemeAnimationDuration,
|
||||
),
|
||||
],
|
||||
|
|
@ -504,29 +511,25 @@ class _CustomStepperState extends State<CustomStepper> {
|
|||
final List<Widget> children = <Widget>[];
|
||||
|
||||
for (int i = 0; i < widget.steps.length; i += 1) {
|
||||
children.add(
|
||||
new Column(
|
||||
key: _keys[i],
|
||||
children: <Widget>[
|
||||
new InkWell(
|
||||
onTap: widget.steps[i].state != CustomStepState.disabled ? () {
|
||||
// In the vertical case we need to scroll to the newly tapped
|
||||
// step.
|
||||
Scrollable.ensureVisible(
|
||||
_keys[i].currentContext,
|
||||
curve: Curves.fastOutSlowIn,
|
||||
duration: kThemeAnimationDuration,
|
||||
);
|
||||
children.add(new Column(key: _keys[i], children: <Widget>[
|
||||
new InkWell(
|
||||
onTap: widget.steps[i].state != CustomStepState.disabled
|
||||
? () {
|
||||
// In the vertical case we need to scroll to the newly tapped
|
||||
// step.
|
||||
Scrollable.ensureVisible(
|
||||
_keys[i].currentContext,
|
||||
curve: Curves.fastOutSlowIn,
|
||||
duration: kThemeAnimationDuration,
|
||||
);
|
||||
|
||||
if (widget.onCustomStepTapped != null)
|
||||
widget.onCustomStepTapped(i);
|
||||
} : null,
|
||||
child: _buildVerticalHeader(i)
|
||||
),
|
||||
_buildVerticalBody(i)
|
||||
]
|
||||
)
|
||||
);
|
||||
if (widget.onCustomStepTapped != null)
|
||||
widget.onCustomStepTapped(i);
|
||||
}
|
||||
: null,
|
||||
child: _buildVerticalHeader(i)),
|
||||
_buildVerticalBody(i)
|
||||
]));
|
||||
}
|
||||
|
||||
return new ListView(
|
||||
|
|
@ -541,10 +544,12 @@ class _CustomStepperState extends State<CustomStepper> {
|
|||
for (int i = 0; i < widget.steps.length; i += 1) {
|
||||
children.add(
|
||||
new InkResponse(
|
||||
onTap: widget.steps[i].state != CustomStepState.disabled ? () {
|
||||
if (widget.onCustomStepTapped != null)
|
||||
widget.onCustomStepTapped(i);
|
||||
} : null,
|
||||
onTap: widget.steps[i].state != CustomStepState.disabled
|
||||
? () {
|
||||
if (widget.onCustomStepTapped != null)
|
||||
widget.onCustomStepTapped(i);
|
||||
}
|
||||
: null,
|
||||
child: new Row(
|
||||
children: <Widget>[
|
||||
new Container(
|
||||
|
|
@ -593,7 +598,7 @@ class _CustomStepperState extends State<CustomStepper> {
|
|||
new AnimatedSize(
|
||||
curve: Curves.fastOutSlowIn,
|
||||
duration: kThemeAnimationDuration,
|
||||
//vsync: this,
|
||||
vsync: null,
|
||||
child: widget.steps[widget.currentCustomStep].content,
|
||||
),
|
||||
_buildVerticalControls(),
|
||||
|
|
@ -608,12 +613,11 @@ class _CustomStepperState extends State<CustomStepper> {
|
|||
Widget build(BuildContext context) {
|
||||
assert(debugCheckHasMaterial(context));
|
||||
assert(() {
|
||||
if (context.ancestorWidgetOfExactType(CustomStepper) != null)
|
||||
if (context.findAncestorWidgetOfExactType<CustomStepper>() != null)
|
||||
throw new FlutterError(
|
||||
'CustomSteppers must not be nested. The material specification advises '
|
||||
'CustomSteppers must not be nested. The material specification advises '
|
||||
'that one should avoid embedding steppers within steppers. '
|
||||
'https://material.google.com/components/steppers.html#steppers-usage\n'
|
||||
);
|
||||
'https://material.google.com/components/steppers.html#steppers-usage\n');
|
||||
return true;
|
||||
}());
|
||||
assert(widget.type != null);
|
||||
|
|
@ -630,9 +634,7 @@ class _CustomStepperState extends State<CustomStepper> {
|
|||
// Paints a triangle whose base is the bottom of the bounding rectangle and its
|
||||
// top vertex the middle of its top.
|
||||
class _TrianglePainter extends CustomPainter {
|
||||
_TrianglePainter({
|
||||
this.color
|
||||
});
|
||||
_TrianglePainter({this.color});
|
||||
|
||||
final Color color;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue