Fix thumb size calculation (#36887)
Cupertino's thumb would jump up/down in size at the overscroll boundary, and this fixes it.
This commit is contained in:
parent
6f42a68ec4
commit
c8be195e95
@ -214,6 +214,7 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
|
||||
trackExtent * fractionVisible
|
||||
);
|
||||
|
||||
final double fractionOverscrolled = 1.0 - extentInside / _lastMetrics.viewportDimension;
|
||||
final double safeMinLength = math.min(minLength, trackExtent);
|
||||
final double newMinLength = (beforeExtent > 0 && afterExtent > 0)
|
||||
// Thumb extent is no smaller than minLength if scrolling normally.
|
||||
@ -229,7 +230,7 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
|
||||
// [0.8, 1.0] to [0.0, 1.0], so 0% to 20% of overscroll will produce
|
||||
// values for the thumb that range between minLength and the smallest
|
||||
// possible value, minOverscrollLength.
|
||||
: safeMinLength * ((fractionVisible - 0.8).clamp(0.0, 0.2) / 0.2);
|
||||
: safeMinLength * (1.0 - fractionOverscrolled.clamp(0.0, 0.2) / 0.2);
|
||||
|
||||
// The `thumbExtent` should be no greater than `trackSize`, otherwise
|
||||
// the scrollbar may scroll towards the wrong direction.
|
||||
|
@ -371,6 +371,77 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
testWidgets('thumb resizes gradually on overscroll', (WidgetTester tester) async {
|
||||
const EdgeInsets padding = EdgeInsets.fromLTRB(1, 2, 3, 4);
|
||||
const Size size = Size(60, 300);
|
||||
final double scrollExtent = size.height * 10;
|
||||
final ScrollMetrics metrics = defaultMetrics.copyWith(
|
||||
minScrollExtent: 0,
|
||||
maxScrollExtent: scrollExtent,
|
||||
axisDirection: AxisDirection.down,
|
||||
viewportDimension: size.height,
|
||||
);
|
||||
|
||||
const double minOverscrollLength = 8.0;
|
||||
final ScrollbarPainter p = _buildPainter(
|
||||
padding: padding,
|
||||
scrollMetrics: metrics,
|
||||
minLength: 36.0,
|
||||
minOverscrollLength: 8.0,
|
||||
);
|
||||
|
||||
// No overscroll gives a full sized thumb.
|
||||
p.update(
|
||||
metrics.copyWith(
|
||||
pixels: 0.0,
|
||||
),
|
||||
AxisDirection.down,
|
||||
);
|
||||
p.paint(testCanvas, size);
|
||||
final double fullThumbExtent = captureRect().height;
|
||||
expect(fullThumbExtent, greaterThan(_kMinThumbExtent));
|
||||
|
||||
// Scrolling to the middle also gives a full sized thumb.
|
||||
p.update(
|
||||
metrics.copyWith(
|
||||
pixels: scrollExtent / 2,
|
||||
),
|
||||
AxisDirection.down,
|
||||
);
|
||||
p.paint(testCanvas, size);
|
||||
expect(captureRect().height, closeTo(fullThumbExtent, .000001));
|
||||
|
||||
// Scrolling just to the very end also gives a full sized thumb.
|
||||
p.update(
|
||||
metrics.copyWith(
|
||||
pixels: scrollExtent,
|
||||
),
|
||||
AxisDirection.down,
|
||||
);
|
||||
p.paint(testCanvas, size);
|
||||
expect(captureRect().height, closeTo(fullThumbExtent, .000001));
|
||||
|
||||
// Scrolling just past the end shrinks the thumb slightly.
|
||||
p.update(
|
||||
metrics.copyWith(
|
||||
pixels: scrollExtent * 1.001,
|
||||
),
|
||||
AxisDirection.down,
|
||||
);
|
||||
p.paint(testCanvas, size);
|
||||
expect(captureRect().height, closeTo(fullThumbExtent, 2.0));
|
||||
|
||||
// Scrolling way past the end shrinks the thumb to minimum.
|
||||
p.update(
|
||||
metrics.copyWith(
|
||||
pixels: double.infinity,
|
||||
),
|
||||
AxisDirection.down,
|
||||
);
|
||||
p.paint(testCanvas, size);
|
||||
expect(captureRect().height, minOverscrollLength);
|
||||
});
|
||||
|
||||
test('should scroll towards the right direction',
|
||||
() {
|
||||
const Size size = Size(60, 80);
|
||||
|
Loading…
x
Reference in New Issue
Block a user