Make CircularProgressIndicator's stroke width configurable (#9794)

Fixes #9062
This commit is contained in:
Adam Barth 2017-05-19 21:56:07 -07:00 committed by Ian Hickson
parent ab8202dc5a
commit 81b76c2bb8
3 changed files with 71 additions and 30 deletions

View file

@ -11,7 +11,6 @@ import 'theme.dart';
const double _kLinearProgressIndicatorHeight = 6.0;
const double _kMinCircularProgressIndicatorSize = 36.0;
const double _kCircularProgressIndicatorStrokeWidth = 4.0;
// TODO(hansmuller): implement the support for buffer indicator
@ -34,7 +33,7 @@ abstract class ProgressIndicator extends StatefulWidget {
Key key,
this.value,
this.backgroundColor,
this.valueColor
this.valueColor,
}) : super(key: key);
/// If non-null, the value of this progress indicator with 0.0 corresponding
@ -76,7 +75,7 @@ class _LinearProgressIndicatorPainter extends CustomPainter {
this.backgroundColor,
this.valueColor,
this.value,
this.animationValue
this.animationValue,
});
final Color backgroundColor;
@ -139,7 +138,7 @@ class LinearProgressIndicator extends ProgressIndicator {
/// indicator). See [value] for details.
const LinearProgressIndicator({
Key key,
double value
double value,
}) : super(key: key, value: value);
@override
@ -170,16 +169,16 @@ class _LinearProgressIndicatorState extends State<LinearProgressIndicator> with
return new Container(
constraints: const BoxConstraints.tightFor(
width: double.INFINITY,
height: _kLinearProgressIndicatorHeight
height: _kLinearProgressIndicatorHeight,
),
child: new CustomPaint(
painter: new _LinearProgressIndicatorPainter(
backgroundColor: widget._getBackgroundColor(context),
valueColor: widget._getValueColor(context),
value: widget.value, // may be null
animationValue: animationValue // ignored if widget.value is not null
)
)
animationValue: animationValue, // ignored if widget.value is not null
),
),
);
}
@ -192,7 +191,7 @@ class _LinearProgressIndicatorState extends State<LinearProgressIndicator> with
animation: _animation,
builder: (BuildContext context, Widget child) {
return _buildIndicator(context, _animation.value);
}
},
);
}
}
@ -211,7 +210,7 @@ class _CircularProgressIndicatorPainter extends CustomPainter {
this.tailValue,
this.stepValue,
this.rotationValue,
this.strokeWidth
this.strokeWidth,
}) : arcStart = value != null
? _kStartAngle
: _kStartAngle + tailValue * 3 / 2 * math.PI + rotationValue * math.PI * 1.7 - stepValue * 0.8 * math.PI,
@ -282,24 +281,28 @@ class CircularProgressIndicator extends ProgressIndicator {
Key key,
double value,
Color backgroundColor,
Animation<Color> valueColor
Animation<Color> valueColor,
this.strokeWidth: 4.0,
}) : super(key: key, value: value, backgroundColor: backgroundColor, valueColor: valueColor);
/// The width of the line used to draw the circle.
final double strokeWidth;
@override
_CircularProgressIndicatorState createState() => new _CircularProgressIndicatorState();
}
// Tweens used by circular progress indicator
final Animatable<double> _kStrokeHeadTween = new CurveTween(
curve: const Interval(0.0, 0.5, curve: Curves.fastOutSlowIn)
curve: const Interval(0.0, 0.5, curve: Curves.fastOutSlowIn),
).chain(new CurveTween(
curve: const SawTooth(5)
curve: const SawTooth(5),
));
final Animatable<double> _kStrokeTailTween = new CurveTween(
curve: const Interval(0.5, 1.0, curve: Curves.fastOutSlowIn)
curve: const Interval(0.5, 1.0, curve: Curves.fastOutSlowIn),
).chain(new CurveTween(
curve: const SawTooth(5)
curve: const SawTooth(5),
));
final Animatable<int> _kStepTween = new StepTween(begin: 0, end: 5);
@ -338,9 +341,9 @@ class _CircularProgressIndicatorState extends State<CircularProgressIndicator> w
tailValue: tailValue,
stepValue: stepValue,
rotationValue: rotationValue,
strokeWidth: _kCircularProgressIndicatorStrokeWidth
)
)
strokeWidth: widget.strokeWidth,
),
),
);
}
@ -353,9 +356,9 @@ class _CircularProgressIndicatorState extends State<CircularProgressIndicator> w
_kStrokeHeadTween.evaluate(_controller),
_kStrokeTailTween.evaluate(_controller),
_kStepTween.evaluate(_controller),
_kRotationTween.evaluate(_controller)
_kRotationTween.evaluate(_controller),
);
}
},
);
}
@ -376,7 +379,7 @@ class _RefreshProgressIndicatorPainter extends _CircularProgressIndicatorPainter
int stepValue,
double rotationValue,
double strokeWidth,
this.arrowheadScale
this.arrowheadScale,
}) : super(
valueColor: valueColor,
value: value,
@ -384,7 +387,7 @@ class _RefreshProgressIndicatorPainter extends _CircularProgressIndicatorPainter
tailValue: tailValue,
stepValue: stepValue,
rotationValue: rotationValue,
strokeWidth: strokeWidth
strokeWidth: strokeWidth,
);
final double arrowheadScale;
@ -442,12 +445,14 @@ class RefreshProgressIndicator extends CircularProgressIndicator {
Key key,
double value,
Color backgroundColor,
Animation<Color> valueColor
Animation<Color> valueColor,
double strokeWidth: 2.0, // Different default than CircularProgressIndicator.
}) : super(
key: key,
value: value,
backgroundColor: backgroundColor,
valueColor: valueColor
valueColor: valueColor,
strokeWidth: strokeWidth,
);
@override
@ -491,12 +496,12 @@ class _RefreshProgressIndicatorState extends _CircularProgressIndicatorState {
tailValue: tailValue,
stepValue: stepValue,
rotationValue: rotationValue,
strokeWidth: 2.0,
arrowheadScale: arrowheadScale
)
)
)
)
strokeWidth: widget.strokeWidth,
arrowheadScale: arrowheadScale,
),
),
),
),
);
}
}

View file

@ -6,6 +6,8 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/material.dart';
import '../rendering/mock_canvas.dart';
void main() {
// The "can be constructed" tests that follow are primarily to ensure that any
@ -56,4 +58,15 @@ void main() {
final List<Layer> layers2 = tester.layers;
expect(layers1, isNot(equals(layers2)));
});
testWidgets('CircularProgressIndicator stoke width', (WidgetTester tester) async {
await tester.pumpWidget(const CircularProgressIndicator());
expect(find.byType(CircularProgressIndicator), paints..arc(strokeWidth: 4.0));
await tester.pumpWidget(const CircularProgressIndicator(strokeWidth: 16.0));
expect(find.byType(CircularProgressIndicator), paints..arc(strokeWidth: 16.0));
});
}

View file

@ -198,6 +198,18 @@ abstract class PaintPattern {
/// [Canvas.drawLine] call are ignored.
void line({ Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style });
/// Indicates that an arc is expected next.
///
/// The next arc is examined. Any arguments that are passed to this method
/// are compared to the actual [Canvas.drawArc] call's `paint` argument, and
/// any mismatches result in failure.
///
/// If no call to [Canvas.drawArc] was made, then this results in failure.
///
/// Any calls made between the last matched call (if any) and the
/// [Canvas.drawArc] call are ignored.
void arc({ Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style });
/// Indicates that a paragraph is expected next.
///
/// Calls are skipped until a call to [Canvas.drawParagraph] is found. Any
@ -299,6 +311,11 @@ class _TestRecordingCanvasPatternMatcher extends Matcher implements PaintPattern
_predicates.add(new _LinePaintPredicate(color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style));
}
@override
void arc({ Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) {
_predicates.add(new _ArcPaintPredicate(color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style));
}
@override
void paragraph({ ui.Paragraph paragraph, Offset offset }) {
_predicates.add(new _FunctionPaintPredicate(#drawParagraph, <dynamic>[paragraph, offset]));
@ -602,6 +619,12 @@ class _LinePaintPredicate extends _DrawCommandPaintPredicate {
);
}
class _ArcPaintPredicate extends _DrawCommandPaintPredicate {
_ArcPaintPredicate({ Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) : super(
#drawArc, 'an arc', 5, 4, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style
);
}
class _SomethingPaintPredicate extends _PaintPredicate {
_SomethingPaintPredicate(this.predicate);