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
|
trackExtent * fractionVisible
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final double fractionOverscrolled = 1.0 - extentInside / _lastMetrics.viewportDimension;
|
||||||
final double safeMinLength = math.min(minLength, trackExtent);
|
final double safeMinLength = math.min(minLength, trackExtent);
|
||||||
final double newMinLength = (beforeExtent > 0 && afterExtent > 0)
|
final double newMinLength = (beforeExtent > 0 && afterExtent > 0)
|
||||||
// Thumb extent is no smaller than minLength if scrolling normally.
|
// 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
|
// [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
|
// values for the thumb that range between minLength and the smallest
|
||||||
// possible value, minOverscrollLength.
|
// 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 `thumbExtent` should be no greater than `trackSize`, otherwise
|
||||||
// the scrollbar may scroll towards the wrong direction.
|
// 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',
|
test('should scroll towards the right direction',
|
||||||
() {
|
() {
|
||||||
const Size size = Size(60, 80);
|
const Size size = Size(60, 80);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user