Avoid divide by zero in scroll thumb rectangle calculations (#10271)
This commit is contained in:
parent
251d83a4b5
commit
61e938aa1e
@ -156,8 +156,13 @@ class _ScrollbarPainter extends ChangeNotifier implements CustomPainter {
|
|||||||
|
|
||||||
void _paintThumb(double before, double inside, double after, double viewport, Canvas canvas, Size size,
|
void _paintThumb(double before, double inside, double after, double viewport, Canvas canvas, Size size,
|
||||||
void painter(Canvas canvas, Size size, double thumbOffset, double thumbExtent)) {
|
void painter(Canvas canvas, Size size, double thumbOffset, double thumbExtent)) {
|
||||||
final double thumbExtent = math.max(math.min(viewport, _kMinThumbExtent), viewport * inside / (before + inside + after));
|
double thumbExtent = math.min(viewport, _kMinThumbExtent);
|
||||||
final double thumbOffset = before * (viewport - thumbExtent) / (before + after);
|
if (before + inside + after > 0.0)
|
||||||
|
thumbExtent = math.max(thumbExtent, viewport * inside / (before + inside + after));
|
||||||
|
|
||||||
|
final double thumbOffset = (before + after > 0.0) ?
|
||||||
|
before * (viewport - thumbExtent) / (before + after) : 0.0;
|
||||||
|
|
||||||
painter(canvas, size, thumbOffset, thumbExtent);
|
painter(canvas, size, thumbOffset, thumbExtent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,17 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter/scheduler.dart';
|
import 'package:flutter/scheduler.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
class TestCanvas implements Canvas {
|
||||||
|
TestCanvas([this.invocations]);
|
||||||
|
|
||||||
|
final List<Invocation> invocations;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void noSuchMethod(Invocation invocation) {
|
||||||
|
invocations?.add(invocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
testWidgets('Scrollbar doesn\'t show when tapping list', (WidgetTester tester) async {
|
testWidgets('Scrollbar doesn\'t show when tapping list', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
@ -48,4 +59,39 @@ void main() {
|
|||||||
await tester.pump(const Duration(milliseconds: 200));
|
await tester.pump(const Duration(milliseconds: 200));
|
||||||
await tester.pump(const Duration(milliseconds: 200));
|
await tester.pump(const Duration(milliseconds: 200));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('ScrollbarPainter does not divide by zero', (WidgetTester tester) async {
|
||||||
|
await tester.pumpWidget(
|
||||||
|
new Container(
|
||||||
|
height: 200.0,
|
||||||
|
width: 300.0,
|
||||||
|
child: new Scrollbar(
|
||||||
|
child: new ListView(
|
||||||
|
children: <Widget>[
|
||||||
|
new Container(height: 40.0, child: const Text('0')),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
final CustomPaint custom = tester.widget(find.descendant(of: find.byType(Scrollbar), matching: find.byType(CustomPaint)).first);
|
||||||
|
final dynamic scrollPainter = custom.foregroundPainter;
|
||||||
|
final ScrollMetrics metrics = new FixedScrollMetrics(
|
||||||
|
minScrollExtent: 0.0,
|
||||||
|
maxScrollExtent: 0.0,
|
||||||
|
pixels: 0.0,
|
||||||
|
viewportDimension: 100.0,
|
||||||
|
axisDirection: AxisDirection.down
|
||||||
|
);
|
||||||
|
scrollPainter.update(metrics, AxisDirection.down);
|
||||||
|
await tester.pump(const Duration(milliseconds: 200));
|
||||||
|
await tester.pump(const Duration(milliseconds: 200));
|
||||||
|
|
||||||
|
final List<Invocation> invocations = <Invocation>[];
|
||||||
|
final TestCanvas canvas = new TestCanvas(invocations);
|
||||||
|
scrollPainter.paint(canvas, const Size(10.0, 100.0));
|
||||||
|
final Rect thumbRect = invocations.single.positionalArguments[0];
|
||||||
|
expect(thumbRect.isFinite, isTrue);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user