Fix unexpected shown of Scrollbar (#159386)

Fixes [Narrow DatePickerDialog has unnecessary scrollbar on months with
6 rows #141348](https://github.com/flutter/flutter/issues/141348)

## Details

`288 / 7 + 288 / 7 * 6 = 288.00000000000006`

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [ ] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
Flop
2025-01-31 01:33:05 +08:00
committed by GitHub
parent 3e3bb9fdd5
commit 1dd3f5d45b
2 changed files with 50 additions and 7 deletions

View File

@@ -517,9 +517,7 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
_lastMetrics = metrics;
_lastAxisDirection = axisDirection;
bool needPaint(ScrollMetrics? metrics) =>
metrics != null && metrics.maxScrollExtent > metrics.minScrollExtent;
if (!needPaint(oldMetrics) && !needPaint(metrics)) {
if (!_needPaint(oldMetrics) && !_needPaint(metrics)) {
return;
}
notifyListeners();
@@ -537,6 +535,11 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
return Paint()..color = color.withOpacity(color.opacity * fadeoutOpacityAnimation.value);
}
bool _needPaint(ScrollMetrics? metrics) {
return metrics != null &&
metrics.maxScrollExtent - metrics.minScrollExtent > precisionErrorTolerance;
}
Paint _paintTrack({bool isBorder = false}) {
if (isBorder) {
return Paint()
@@ -629,9 +632,7 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
@override
void paint(Canvas canvas, Size size) {
if (_lastAxisDirection == null ||
_lastMetrics == null ||
_lastMetrics!.maxScrollExtent <= _lastMetrics!.minScrollExtent) {
if (_lastAxisDirection == null || !_needPaint(_lastMetrics)) {
return;
}
// Skip painting if there's not enough space.

View File

@@ -5,8 +5,8 @@
import 'dart:ui' as ui;
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/src/physics/utils.dart' show nearEqual;
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
const Color _kScrollbarColor = Color(0xFF123456);
@@ -3484,4 +3484,46 @@ The provided ScrollController cannot be shared by multiple ScrollView widgets.''
expect(verticalScrollController.offset, greaterThan(0.0));
expect(horizontalScrollController.offset, greaterThan(0.0));
});
// Regression test for https://github.com/flutter/flutter/issues/141348.
testWidgets(
'Scrollbar should not shown due to precision error on desktop',
(WidgetTester tester) async {
Widget buildFrame(Size size) {
tester.view.physicalSize = size;
tester.view.devicePixelRatio = 1.0;
addTearDown(tester.view.reset);
return MaterialApp(
home: Scaffold(
body: Center(
child: DatePickerDialog(
initialDate: DateTime(2020, DateTime.may), // Month with six rows.
firstDate: DateTime(2010),
lastDate: DateTime(2030),
),
),
),
);
}
const Size screenSizePortrait = Size(400, 600);
await tester.pumpWidget(buildFrame(screenSizePortrait));
await tester.pumpAndSettle();
// Scrollbar is not shown.
expect(find.byType(Scrollbar), findsOneWidget);
expect(find.byType(Scrollbar), isNot(paints..rect()));
// Scroll on the Scrollbar.
final TestPointer pointer = TestPointer(1, ui.PointerDeviceKind.mouse);
pointer.hover(tester.getCenter(find.byType(Scrollbar)));
await tester.sendEventToBinding(pointer.scroll(const Offset(0.0, 10.0)));
await tester.pumpAndSettle();
// Scrollbar is still not shown.
expect(find.byType(Scrollbar), findsOneWidget);
expect(find.byType(Scrollbar), isNot(paints..rect()));
},
variant: TargetPlatformVariant.desktop(),
);
}