Unverified Commit 9e9ac77d authored by Bernardo Ferrari's avatar Bernardo Ferrari Committed by GitHub

Add `borderRadius` to LinearProgressIndicator (#123517)

Split from https://github.com/flutter/flutter/pull/122664 so it gets easier to review, as this is now unrelated to the `preferRound`. I'm one step from adding a width attribute, lol.

<img width="474" alt="image" src="https://user-images.githubusercontent.com/351125/226083798-71e529e9-4ae9-41de-a500-0412b989a273.png">

cc @Piinks
parent aa5bb7d9
...@@ -145,6 +145,7 @@ class _LinearProgressIndicatorPainter extends CustomPainter { ...@@ -145,6 +145,7 @@ class _LinearProgressIndicatorPainter extends CustomPainter {
this.value, this.value,
required this.animationValue, required this.animationValue,
required this.textDirection, required this.textDirection,
required this.indicatorBorderRadius,
}); });
final Color backgroundColor; final Color backgroundColor;
...@@ -152,6 +153,7 @@ class _LinearProgressIndicatorPainter extends CustomPainter { ...@@ -152,6 +153,7 @@ class _LinearProgressIndicatorPainter extends CustomPainter {
final double? value; final double? value;
final double animationValue; final double animationValue;
final TextDirection textDirection; final TextDirection textDirection;
final BorderRadiusGeometry indicatorBorderRadius;
// The indeterminate progress animation displays two lines whose leading (head) // The indeterminate progress animation displays two lines whose leading (head)
// and trailing (tail) endpoints are defined by the following four curves. // and trailing (tail) endpoints are defined by the following four curves.
...@@ -181,7 +183,6 @@ class _LinearProgressIndicatorPainter extends CustomPainter { ...@@ -181,7 +183,6 @@ class _LinearProgressIndicatorPainter extends CustomPainter {
final Paint paint = Paint() final Paint paint = Paint()
..color = backgroundColor ..color = backgroundColor
..style = PaintingStyle.fill; ..style = PaintingStyle.fill;
canvas.drawRect(Offset.zero & size, paint);
paint.color = valueColor; paint.color = valueColor;
...@@ -197,7 +198,14 @@ class _LinearProgressIndicatorPainter extends CustomPainter { ...@@ -197,7 +198,14 @@ class _LinearProgressIndicatorPainter extends CustomPainter {
case TextDirection.ltr: case TextDirection.ltr:
left = x; left = x;
} }
canvas.drawRect(Offset(left, 0.0) & Size(width, size.height), paint);
final Rect rect = Offset(left, 0.0) & Size(width, size.height);
if (indicatorBorderRadius != BorderRadius.zero) {
final RRect rrect = indicatorBorderRadius.resolve(textDirection).toRRect(rect);
canvas.drawRRect(rrect, paint);
} else {
canvas.drawRect(rect, paint);
}
} }
if (value != null) { if (value != null) {
...@@ -220,7 +228,8 @@ class _LinearProgressIndicatorPainter extends CustomPainter { ...@@ -220,7 +228,8 @@ class _LinearProgressIndicatorPainter extends CustomPainter {
|| oldPainter.valueColor != valueColor || oldPainter.valueColor != valueColor
|| oldPainter.value != value || oldPainter.value != value
|| oldPainter.animationValue != animationValue || oldPainter.animationValue != animationValue
|| oldPainter.textDirection != textDirection; || oldPainter.textDirection != textDirection
|| oldPainter.indicatorBorderRadius != indicatorBorderRadius;
} }
} }
...@@ -279,6 +288,7 @@ class LinearProgressIndicator extends ProgressIndicator { ...@@ -279,6 +288,7 @@ class LinearProgressIndicator extends ProgressIndicator {
this.minHeight, this.minHeight,
super.semanticsLabel, super.semanticsLabel,
super.semanticsValue, super.semanticsValue,
this.borderRadius = BorderRadius.zero,
}) : assert(minHeight == null || minHeight > 0); }) : assert(minHeight == null || minHeight > 0);
/// {@template flutter.material.LinearProgressIndicator.trackColor} /// {@template flutter.material.LinearProgressIndicator.trackColor}
...@@ -301,6 +311,12 @@ class LinearProgressIndicator extends ProgressIndicator { ...@@ -301,6 +311,12 @@ class LinearProgressIndicator extends ProgressIndicator {
/// {@endtemplate} /// {@endtemplate}
final double? minHeight; final double? minHeight;
/// The border radius of both the indicator and the track.
///
/// By default it is [BorderRadius.zero], which produces a rectangular shape
/// with a rectangular indicator.
final BorderRadiusGeometry borderRadius;
@override @override
State<LinearProgressIndicator> createState() => _LinearProgressIndicatorState(); State<LinearProgressIndicator> createState() => _LinearProgressIndicatorState();
} }
...@@ -352,6 +368,14 @@ class _LinearProgressIndicatorState extends State<LinearProgressIndicator> with ...@@ -352,6 +368,14 @@ class _LinearProgressIndicatorState extends State<LinearProgressIndicator> with
return widget._buildSemanticsWrapper( return widget._buildSemanticsWrapper(
context: context, context: context,
child: Container( child: Container(
// Clip is only needed with indeterminate progress indicators
clipBehavior: (widget.borderRadius != BorderRadius.zero && widget.value == null)
? Clip.antiAlias
: Clip.none,
decoration: ShapeDecoration(
color: trackColor,
shape: RoundedRectangleBorder(borderRadius: widget.borderRadius),
),
constraints: BoxConstraints( constraints: BoxConstraints(
minWidth: double.infinity, minWidth: double.infinity,
minHeight: minHeight, minHeight: minHeight,
...@@ -363,6 +387,7 @@ class _LinearProgressIndicatorState extends State<LinearProgressIndicator> with ...@@ -363,6 +387,7 @@ class _LinearProgressIndicatorState extends State<LinearProgressIndicator> with
value: widget.value, // may be null value: widget.value, // may be null
animationValue: animationValue, // ignored if widget.value is not null animationValue: animationValue, // ignored if widget.value is not null
textDirection: textDirection, textDirection: textDirection,
indicatorBorderRadius: widget.borderRadius,
), ),
), ),
), ),
......
...@@ -465,6 +465,41 @@ void main() { ...@@ -465,6 +465,41 @@ void main() {
expect(find.byType(CircularProgressIndicator), paints..arc(strokeCap: StrokeCap.round)); expect(find.byType(CircularProgressIndicator), paints..arc(strokeCap: StrokeCap.round));
}); });
testWidgets('LinearProgressIndicator with indicatorBorderRadius', (WidgetTester tester) async {
await tester.pumpWidget(
Theme(
data: theme,
child: const Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: SizedBox(
width: 100.0,
height: 4.0,
child: LinearProgressIndicator(
value: 0.25,
borderRadius: BorderRadius.all(Radius.circular(10)),
),
),
),
),
),
);
expect(
find.byType(LinearProgressIndicator),
paints
..rrect(
rrect: RRect.fromLTRBR(0.0, 0.0, 100.0, 4.0, const Radius.circular(10.0)),
)
..rrect(
rrect: RRect.fromRectAndRadius(
const Rect.fromLTRB(0.0, 0.0, 25.0, 4.0),
const Radius.circular(10.0),
),
),
);
expect(tester.binding.transientCallbackCount, 0);
});
testWidgets('CircularProgressIndicator paint colors', (WidgetTester tester) async { testWidgets('CircularProgressIndicator paint colors', (WidgetTester tester) async {
const Color green = Color(0xFF00FF00); const Color green = Color(0xFF00FF00);
const Color blue = Color(0xFF0000FF); const Color blue = Color(0xFF0000FF);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment