mirror of
https://github.com/flutter/flutter.git
synced 2026-02-13 14:21:39 +08:00
adds trackRadius to ScrollbarPainter and RawScrollbar (#98018)
This commit is contained in:
parent
9369bd3222
commit
281f1421df
@ -86,6 +86,7 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
|
||||
double mainAxisMargin = 0.0,
|
||||
double crossAxisMargin = 0.0,
|
||||
Radius? radius,
|
||||
Radius? trackRadius,
|
||||
OutlinedBorder? shape,
|
||||
double minLength = _kMinThumbExtent,
|
||||
double? minOverscrollLength,
|
||||
@ -117,6 +118,7 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
|
||||
_minLength = minLength,
|
||||
_trackColor = trackColor,
|
||||
_trackBorderColor = trackBorderColor,
|
||||
_trackRadius = trackRadius,
|
||||
_scrollbarOrientation = scrollbarOrientation,
|
||||
_minOverscrollLength = minOverscrollLength ?? minLength,
|
||||
_ignorePointer = ignorePointer {
|
||||
@ -159,6 +161,19 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// [Radius] of corners of the Scrollbar's track.
|
||||
///
|
||||
/// Scrollbar's track will be rectangular if [trackRadius] is null.
|
||||
Radius? get trackRadius => _trackRadius;
|
||||
Radius? _trackRadius;
|
||||
set trackRadius(Radius? value) {
|
||||
if (trackRadius == value)
|
||||
return;
|
||||
|
||||
_trackRadius = value;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// [TextDirection] of the [BuildContext] which dictates the side of the
|
||||
/// screen the scrollbar appears in (the trailing side). Must be set prior to
|
||||
/// calling paint.
|
||||
@ -496,7 +511,11 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
|
||||
// Paint if the opacity dictates visibility
|
||||
if (fadeoutOpacityAnimation.value != 0.0) {
|
||||
// Track
|
||||
canvas.drawRect(_trackRect!, _paintTrack());
|
||||
if (trackRadius == null) {
|
||||
canvas.drawRect(_trackRect!, _paintTrack());
|
||||
} else {
|
||||
canvas.drawRRect(RRect.fromRectAndRadius(_trackRect!, trackRadius!), _paintTrack());
|
||||
}
|
||||
// Track Border
|
||||
canvas.drawLine(borderStart, borderEnd, _paintTrack(isBorder: true));
|
||||
if (radius != null) {
|
||||
@ -741,6 +760,7 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
|
||||
|| mainAxisMargin != oldDelegate.mainAxisMargin
|
||||
|| crossAxisMargin != oldDelegate.crossAxisMargin
|
||||
|| radius != oldDelegate.radius
|
||||
|| trackRadius != oldDelegate.trackRadius
|
||||
|| shape != oldDelegate.shape
|
||||
|| padding != oldDelegate.padding
|
||||
|| minLength != oldDelegate.minLength
|
||||
@ -880,6 +900,7 @@ class RawScrollbar extends StatefulWidget {
|
||||
this.minThumbLength = _kMinThumbExtent,
|
||||
this.minOverscrollLength,
|
||||
this.trackVisibility,
|
||||
this.trackRadius,
|
||||
this.trackColor,
|
||||
this.trackBorderColor,
|
||||
this.fadeDuration = _kScrollbarFadeDuration,
|
||||
@ -1224,6 +1245,12 @@ class RawScrollbar extends StatefulWidget {
|
||||
/// [MaterialState]s by using [ScrollbarThemeData.trackVisibility].
|
||||
final bool? trackVisibility;
|
||||
|
||||
/// The [Radius] of the scrollbar track's rounded rectangle corners.
|
||||
///
|
||||
/// Scrollbar's track will be rectangular if [trackRadius] is null, which is
|
||||
/// the default behavior.
|
||||
final Radius? trackRadius;
|
||||
|
||||
/// The color of the scrollbar track.
|
||||
///
|
||||
/// The scrollbar track will only be visible when [trackVisibility] and
|
||||
@ -1380,6 +1407,7 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv
|
||||
fadeoutOpacityAnimation: _fadeoutOpacityAnimation,
|
||||
thickness: widget.thickness ?? _kScrollbarThickness,
|
||||
radius: widget.radius,
|
||||
trackRadius: widget.trackRadius,
|
||||
scrollbarOrientation: widget.scrollbarOrientation,
|
||||
mainAxisMargin: widget.mainAxisMargin,
|
||||
shape: widget.shape,
|
||||
@ -1513,6 +1541,7 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv
|
||||
void updateScrollbarPainter() {
|
||||
scrollbarPainter
|
||||
..color = widget.thumbColor ?? const Color(0x66BCBCBC)
|
||||
..trackRadius = widget.trackRadius
|
||||
..trackColor = _showTrack ? const Color(0x08000000) : const Color(0x00000000)
|
||||
..trackBorderColor = _showTrack ? const Color(0x1a000000) : const Color(0x00000000)
|
||||
..textDirection = Directionality.of(context)
|
||||
|
||||
@ -25,6 +25,7 @@ ScrollbarPainter _buildPainter({
|
||||
double mainAxisMargin = 0.0,
|
||||
double crossAxisMargin = 0.0,
|
||||
Radius? radius,
|
||||
Radius? trackRadius,
|
||||
double minLength = _kMinThumbExtent,
|
||||
double? minOverscrollLength,
|
||||
ScrollbarOrientation? scrollbarOrientation,
|
||||
@ -38,6 +39,7 @@ ScrollbarPainter _buildPainter({
|
||||
mainAxisMargin: mainAxisMargin,
|
||||
crossAxisMargin: crossAxisMargin,
|
||||
radius: radius,
|
||||
trackRadius: trackRadius,
|
||||
minLength: minLength,
|
||||
minOverscrollLength: minOverscrollLength ?? minLength,
|
||||
fadeoutOpacityAnimation: kAlwaysCompleteAnimation,
|
||||
@ -47,12 +49,18 @@ ScrollbarPainter _buildPainter({
|
||||
|
||||
class _DrawRectOnceCanvas extends Fake implements Canvas {
|
||||
List<Rect> rects = <Rect>[];
|
||||
List<RRect> rrects = <RRect>[];
|
||||
|
||||
@override
|
||||
void drawRect(Rect rect, Paint paint) {
|
||||
rects.add(rect);
|
||||
}
|
||||
|
||||
@override
|
||||
void drawRRect(ui.RRect rrect, ui.Paint paint) {
|
||||
rrects.add(rrect);
|
||||
}
|
||||
|
||||
@override
|
||||
void drawLine(Offset p1, Offset p2, Paint paint) {}
|
||||
}
|
||||
@ -62,9 +70,11 @@ void main() {
|
||||
ScrollbarPainter painter;
|
||||
|
||||
Rect captureRect() => testCanvas.rects.removeLast();
|
||||
RRect captureRRect() => testCanvas.rrects.removeLast();
|
||||
|
||||
tearDown(() {
|
||||
testCanvas.rects.clear();
|
||||
testCanvas.rrects.clear();
|
||||
});
|
||||
|
||||
final ScrollMetrics defaultMetrics = FixedScrollMetrics(
|
||||
@ -629,6 +639,37 @@ void main() {
|
||||
},
|
||||
);
|
||||
|
||||
test('trackRadius and radius is respected', () {
|
||||
const double minLen = 3.5;
|
||||
const Size size = Size(600, 10);
|
||||
final ScrollMetrics metrics = defaultMetrics.copyWith(
|
||||
maxScrollExtent: 100000,
|
||||
viewportDimension: size.height,
|
||||
);
|
||||
|
||||
painter = _buildPainter(
|
||||
trackRadius: const Radius.circular(2.0),
|
||||
radius: const Radius.circular(3.0),
|
||||
minLength: minLen,
|
||||
minOverscrollLength: minLen,
|
||||
scrollMetrics: metrics,
|
||||
);
|
||||
|
||||
painter.paint(testCanvas, size);
|
||||
|
||||
final RRect thumbRRect = captureRRect(); // thumb
|
||||
expect(thumbRRect.blRadius, const Radius.circular(3.0));
|
||||
expect(thumbRRect.brRadius, const Radius.circular(3.0));
|
||||
expect(thumbRRect.tlRadius, const Radius.circular(3.0));
|
||||
expect(thumbRRect.trRadius, const Radius.circular(3.0));
|
||||
|
||||
final RRect trackRRect = captureRRect(); // track
|
||||
expect(trackRRect.blRadius, const Radius.circular(2.0));
|
||||
expect(trackRRect.brRadius, const Radius.circular(2.0));
|
||||
expect(trackRRect.tlRadius, const Radius.circular(2.0));
|
||||
expect(trackRRect.trRadius, const Radius.circular(2.0));
|
||||
});
|
||||
|
||||
testWidgets('ScrollbarPainter asserts if no TextDirection has been provided', (WidgetTester tester) async {
|
||||
final ScrollbarPainter painter = ScrollbarPainter(
|
||||
color: _kScrollbarColor,
|
||||
@ -691,7 +732,7 @@ void main() {
|
||||
..rect(
|
||||
rect: const Rect.fromLTRB(794.0, 240.0, 800.0, 600.0),
|
||||
color: const Color(0x66BCBCBC),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Tap on the track area above the thumb.
|
||||
@ -706,7 +747,7 @@ void main() {
|
||||
..rect(
|
||||
rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 360.0),
|
||||
color: const Color(0x66BCBCBC),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
@ -736,7 +777,7 @@ void main() {
|
||||
..rect(
|
||||
rect: const Rect.fromLTRB(794.0, 3.0, 800.0, 93.0),
|
||||
color: const Color(0x66BCBCBC),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pump(const Duration(seconds: 3));
|
||||
@ -749,7 +790,7 @@ void main() {
|
||||
..rect(
|
||||
rect: const Rect.fromLTRB(794.0, 3.0, 800.0, 93.0),
|
||||
color: const Color(0x66BCBCBC),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await gesture.up();
|
||||
@ -764,7 +805,7 @@ void main() {
|
||||
..rect(
|
||||
rect: const Rect.fromLTRB(794.0, 3.0, 800.0, 93.0),
|
||||
color: const Color(0x4fbcbcbc),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
@ -794,7 +835,7 @@ void main() {
|
||||
..rect(
|
||||
rect: const Rect.fromLTRB(794.0, 3.0, 800.0, 93.0),
|
||||
color: const Color(0x66BCBCBC),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final TestPointer testPointer = TestPointer(1, ui.PointerDeviceKind.mouse);
|
||||
@ -811,7 +852,7 @@ void main() {
|
||||
..rect(
|
||||
rect: const Rect.fromLTRB(794.0, 3.0, 800.0, 93.0),
|
||||
color: const Color(0x66BCBCBC),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
@ -940,7 +981,7 @@ void main() {
|
||||
..rect(
|
||||
rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 90.0),
|
||||
color: const Color(0x66BCBCBC),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Drag the thumb down to scroll down.
|
||||
@ -962,7 +1003,7 @@ void main() {
|
||||
..rect(
|
||||
rect: const Rect.fromLTRB(794.0, 10.0, 800.0, 100.0),
|
||||
color: const Color(0x66BCBCBC),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
@ -2206,6 +2247,7 @@ void main() {
|
||||
double mainAxisMargin = 0.0,
|
||||
double crossAxisMargin = 0.0,
|
||||
Radius? radius,
|
||||
Radius? trackRadius,
|
||||
OutlinedBorder? shape,
|
||||
double minLength = _kMinThumbExtent,
|
||||
double? minOverscrollLength,
|
||||
@ -2222,6 +2264,7 @@ void main() {
|
||||
mainAxisMargin: mainAxisMargin,
|
||||
crossAxisMargin: crossAxisMargin,
|
||||
radius: radius,
|
||||
trackRadius: trackRadius,
|
||||
shape: shape,
|
||||
minLength: minLength,
|
||||
minOverscrollLength: minOverscrollLength,
|
||||
@ -2240,6 +2283,7 @@ void main() {
|
||||
expect(painter.shouldRepaint(createPainter(mainAxisMargin: 1.0)), true);
|
||||
expect(painter.shouldRepaint(createPainter(crossAxisMargin: 1.0)), true);
|
||||
expect(painter.shouldRepaint(createPainter(radius: const Radius.circular(1.0))), true);
|
||||
expect(painter.shouldRepaint(createPainter(trackRadius: const Radius.circular(1.0))), true);
|
||||
expect(painter.shouldRepaint(createPainter(shape: const CircleBorder(side: BorderSide(width: 2.0)))), true);
|
||||
expect(painter.shouldRepaint(createPainter(minLength: _kMinThumbExtent + 1.0)), true);
|
||||
expect(painter.shouldRepaint(createPainter(minOverscrollLength: 1.0)), true);
|
||||
@ -2289,6 +2333,45 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('trackRadius and radius properties of RawScrollbar can draw RoundedRectangularRect', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: MediaQuery(
|
||||
data: const MediaQueryData(),
|
||||
child: PrimaryScrollController(
|
||||
controller: scrollController,
|
||||
child: RawScrollbar(
|
||||
thumbVisibility: true,
|
||||
trackVisibility: true,
|
||||
trackRadius: const Radius.circular(1.0),
|
||||
radius: const Radius.circular(2.0),
|
||||
controller: scrollController,
|
||||
child: const SingleChildScrollView(
|
||||
child: SizedBox(width: 4000.0, height: 4000.0),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
expect(scrollController.offset, 0.0);
|
||||
expect(
|
||||
find.byType(RawScrollbar),
|
||||
paints
|
||||
..rrect(
|
||||
rrect: RRect.fromLTRBR(794.0, 0.0, 800.0, 600.0, const Radius.circular(1.0)),
|
||||
color: const Color(0x08000000),
|
||||
)
|
||||
..rrect(
|
||||
rrect: RRect.fromLTRBR(794.0, 0.0, 800.0, 90.0, const Radius.circular(2.0)),
|
||||
color: const Color(0x66bcbcbc),
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Scrollbar asserts that a visible track has a visible thumb', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
Widget _buildApp() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user