Skip to content

Commit 2d2ebbe

Browse files
authored
Fix GlowingOverscrollIndicator examples (#155203)
Part of flutter/flutter#130459 This pull request adds tests for the example files shown in the [GlowingOverscrollIndicator](https://api.flutter.dev/flutter/widgets/GlowingOverscrollIndicator-class.html) Flutter API reference documentation.
1 parent bb08ec9 commit 2d2ebbe

File tree

5 files changed

+245
-14
lines changed

5 files changed

+245
-14
lines changed

dev/bots/check_code_samples.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,4 @@ final Set<String> _knownMissingTests = <String>{
321321
'examples/api/test/widgets/interactive_viewer/interactive_viewer.constrained.0_test.dart',
322322
'examples/api/test/widgets/interactive_viewer/interactive_viewer.transformation_controller.0_test.dart',
323323
'examples/api/test/widgets/notification_listener/notification.0_test.dart',
324-
'examples/api/test/widgets/overscroll_indicator/glowing_overscroll_indicator.1_test.dart',
325-
'examples/api/test/widgets/overscroll_indicator/glowing_overscroll_indicator.0_test.dart',
326324
};

examples/api/lib/widgets/overscroll_indicator/glowing_overscroll_indicator.0.dart

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
import 'package:flutter/gestures.dart';
56
import 'package:flutter/material.dart';
67

78
/// Flutter code sample for [GlowingOverscrollIndicator].
@@ -14,6 +15,8 @@ class GlowingOverscrollIndicatorExampleApp extends StatelessWidget {
1415
@override
1516
Widget build(BuildContext context) {
1617
return MaterialApp(
18+
scrollBehavior: const AlwaysGlow(),
19+
theme: ThemeData(colorSchemeSeed: Colors.amber),
1720
home: Scaffold(
1821
appBar: AppBar(title: const Text('GlowingOverscrollIndicator Sample')),
1922
body: const GlowingOverscrollIndicatorExample(),
@@ -22,30 +25,71 @@ class GlowingOverscrollIndicatorExampleApp extends StatelessWidget {
2225
}
2326
}
2427

28+
const Set<PointerDeviceKind> allPointers = <PointerDeviceKind>{...PointerDeviceKind.values};
29+
30+
// Passing this class into the MaterialApp constructor ensures that a
31+
// GlowingOverscrollIndicator is created, regardless of the target platform.
32+
class AlwaysGlow extends MaterialScrollBehavior {
33+
const AlwaysGlow();
34+
35+
@override
36+
Set<PointerDeviceKind> get dragDevices => allPointers;
37+
38+
@override
39+
Widget buildOverscrollIndicator(
40+
BuildContext context,
41+
Widget child,
42+
ScrollableDetails details,
43+
) {
44+
return GlowingOverscrollIndicator(
45+
axisDirection: details.direction,
46+
color: Colors.amberAccent,
47+
child: child,
48+
);
49+
}
50+
}
51+
2552
class GlowingOverscrollIndicatorExample extends StatelessWidget {
2653
const GlowingOverscrollIndicatorExample({super.key});
2754

2855
@override
2956
Widget build(BuildContext context) {
30-
final double leadingPaintOffset = MediaQuery.of(context).padding.top + AppBar().preferredSize.height;
57+
final double leadingPaintOffset = MediaQuery.paddingOf(context).top + kToolbarHeight;
58+
3159
return NotificationListener<OverscrollIndicatorNotification>(
3260
onNotification: (OverscrollIndicatorNotification notification) {
3361
if (notification.leading) {
3462
notification.paintOffset = leadingPaintOffset;
3563
}
3664
return false;
3765
},
38-
child: CustomScrollView(
66+
child: const CustomScrollView(
3967
slivers: <Widget>[
40-
const SliverAppBar(title: Text('Custom PaintOffset')),
68+
SliverAppBar(title: Text('Custom PaintOffset')),
4169
SliverToBoxAdapter(
42-
child: Container(
70+
child: DefaultTextStyle(
71+
style: TextStyle(
72+
color: Colors.amberAccent,
73+
fontSize: 24,
74+
fontWeight: FontWeight.w600,
75+
),
76+
child: ColoredBox(
77+
color: Colors.grey,
78+
child: SizedBox(
79+
width: double.infinity,
80+
height: 80,
81+
child: Center(child: Text('Glow all day!')),
82+
),
83+
),
84+
),
85+
),
86+
SliverFillRemaining(
87+
child: Icon(
88+
Icons.sunny,
4389
color: Colors.amberAccent,
44-
height: 100,
45-
child: const Center(child: Text('Glow all day!')),
90+
size: 128,
4691
),
4792
),
48-
const SliverFillRemaining(child: FlutterLogo()),
4993
],
5094
),
5195
);

examples/api/lib/widgets/overscroll_indicator/glowing_overscroll_indicator.1.dart

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
import 'package:flutter/gestures.dart';
56
import 'package:flutter/material.dart';
67

78
/// Flutter code sample for [GlowingOverscrollIndicator].
@@ -14,6 +15,8 @@ class GlowingOverscrollIndicatorExampleApp extends StatelessWidget {
1415
@override
1516
Widget build(BuildContext context) {
1617
return MaterialApp(
18+
scrollBehavior: const AlwaysGlow(),
19+
theme: ThemeData(colorSchemeSeed: Colors.amber),
1720
home: Scaffold(
1821
appBar: AppBar(title: const Text('GlowingOverscrollIndicator Sample')),
1922
body: const GlowingOverscrollIndicatorExample(),
@@ -22,6 +25,31 @@ class GlowingOverscrollIndicatorExampleApp extends StatelessWidget {
2225
}
2326
}
2427

28+
const Set<PointerDeviceKind> allPointers = <PointerDeviceKind>{...PointerDeviceKind.values};
29+
30+
// Passing this class into the MaterialApp constructor ensures that a
31+
// GlowingOverscrollIndicator is created, regardless of the target platform.
32+
class AlwaysGlow extends MaterialScrollBehavior {
33+
const AlwaysGlow();
34+
35+
@override
36+
Set<PointerDeviceKind> get dragDevices => allPointers;
37+
38+
@override
39+
Widget buildOverscrollIndicator(
40+
BuildContext context,
41+
Widget child,
42+
ScrollableDetails details,
43+
) {
44+
return GlowingOverscrollIndicator(
45+
axisDirection: details.direction,
46+
color: Colors.amberAccent,
47+
child: child,
48+
);
49+
}
50+
}
51+
52+
2553
class GlowingOverscrollIndicatorExample extends StatelessWidget {
2654
const GlowingOverscrollIndicatorExample({super.key});
2755

@@ -33,16 +61,32 @@ class GlowingOverscrollIndicatorExample extends StatelessWidget {
3361
SliverAppBar(title: Text('Custom NestedScrollViews')),
3462
];
3563
},
36-
body: CustomScrollView(
64+
body: const CustomScrollView(
3765
slivers: <Widget>[
3866
SliverToBoxAdapter(
39-
child: Container(
67+
child: DefaultTextStyle(
68+
style: TextStyle(
69+
color: Colors.amberAccent,
70+
fontSize: 24,
71+
fontWeight: FontWeight.w600,
72+
),
73+
child: ColoredBox(
74+
color: Colors.grey,
75+
child: SizedBox(
76+
width: double.infinity,
77+
height: 80,
78+
child: Center(child: Text('Glow all day!')),
79+
),
80+
),
81+
),
82+
),
83+
SliverFillRemaining(
84+
child: Icon(
85+
Icons.sunny,
4086
color: Colors.amberAccent,
41-
height: 100,
42-
child: const Center(child: Text('Glow all day!')),
87+
size: 128,
4388
),
4489
),
45-
const SliverFillRemaining(child: FlutterLogo()),
4690
],
4791
),
4892
);
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/material.dart';
6+
import 'package:flutter/rendering.dart';
7+
import 'package:flutter_api_samples/widgets/overscroll_indicator/glowing_overscroll_indicator.0.dart' as example;
8+
import 'package:flutter_test/flutter_test.dart';
9+
10+
void main() {
11+
testWidgets('Displays widget tree when the example app is run', (WidgetTester tester) async {
12+
await tester.pumpWidget(const example.GlowingOverscrollIndicatorExampleApp());
13+
14+
expect(find.descendant(
15+
of: find.byType(Scaffold),
16+
matching: find.widgetWithText(AppBar, 'GlowingOverscrollIndicator Sample'),
17+
), findsOne);
18+
19+
final Finder customScrollViewFinder = find.byType(CustomScrollView);
20+
final Finder sliverAppBarFinder = find.descendant(
21+
of: customScrollViewFinder,
22+
matching: find.widgetWithText(SliverAppBar, 'Custom PaintOffset'),
23+
);
24+
25+
expect(sliverAppBarFinder, findsOne);
26+
27+
expect(find.descendant(
28+
of: customScrollViewFinder,
29+
matching: find.widgetWithText(Center, 'Glow all day!'),
30+
), findsOne);
31+
32+
expect(find.descendant(
33+
of: customScrollViewFinder,
34+
matching: find.byType(SliverToBoxAdapter),
35+
), findsOne);
36+
37+
expect(find.descendant(
38+
of: customScrollViewFinder,
39+
matching: find.widgetWithIcon(SliverFillRemaining, Icons.sunny),
40+
), findsOne);
41+
42+
expect(find.descendant(
43+
of: customScrollViewFinder,
44+
matching: find.byType(GlowingOverscrollIndicator),
45+
), findsOne);
46+
47+
// Check if GlowingOverscrollIndicator overlays the SliverAppBar.
48+
final RenderBox overscrollIndicator = tester.renderObject<RenderBox>(
49+
find.descendant(
50+
of: customScrollViewFinder,
51+
matching: find.byType(GlowingOverscrollIndicator),
52+
),
53+
);
54+
final RenderSliver sliverAppBar = tester.renderObject<RenderSliver>(sliverAppBarFinder);
55+
final Matrix4 transform = overscrollIndicator.getTransformTo(sliverAppBar);
56+
final Offset? offset = MatrixUtils.getAsTranslation(transform);
57+
expect(offset?.dy, 0);
58+
});
59+
60+
testWidgets('Triggers a notification listener when the screen is dragged', (WidgetTester tester) async {
61+
bool overscrollNotified = false;
62+
double leadingPaintOffset = 0.0;
63+
64+
await tester.pumpWidget(
65+
NotificationListener<OverscrollIndicatorNotification>(
66+
onNotification: (OverscrollIndicatorNotification notification) {
67+
overscrollNotified = true;
68+
leadingPaintOffset = notification.paintOffset;
69+
return false;
70+
},
71+
child: const example.GlowingOverscrollIndicatorExampleApp(),
72+
),
73+
);
74+
75+
expect(leadingPaintOffset, 0);
76+
expect(overscrollNotified, isFalse);
77+
final BuildContext context = tester.element(find.byType(MaterialApp));
78+
79+
await tester.drag(find.byType(CustomScrollView), const Offset(0, 500));
80+
await tester.pump();
81+
82+
expect(leadingPaintOffset, MediaQuery.paddingOf(context).top + kToolbarHeight);
83+
expect(overscrollNotified, isTrue);
84+
});
85+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/material.dart';
6+
import 'package:flutter/rendering.dart';
7+
import 'package:flutter_api_samples/widgets/overscroll_indicator/glowing_overscroll_indicator.1.dart' as example;
8+
import 'package:flutter_test/flutter_test.dart';
9+
10+
void main() {
11+
testWidgets('Displays widget tree when the example app is run', (WidgetTester tester) async {
12+
await tester.pumpWidget(const example.GlowingOverscrollIndicatorExampleApp());
13+
14+
expect(find.descendant(
15+
of: find.byType(Scaffold),
16+
matching: find.widgetWithText(AppBar, 'GlowingOverscrollIndicator Sample'),
17+
), findsOne);
18+
19+
expect(find.descendant(
20+
of: find.byType(NestedScrollView),
21+
matching: find.widgetWithText(SliverAppBar, 'Custom NestedScrollViews'),
22+
), findsOne);
23+
24+
expect(find.descendant(
25+
of: find.byType(NestedScrollView),
26+
matching: find.widgetWithText(Center, 'Glow all day!'),
27+
), findsOne);
28+
29+
final Finder customScrollViewFinder = find.byType(CustomScrollView);
30+
31+
expect(find.descendant(
32+
of: customScrollViewFinder,
33+
matching: find.byType(SliverToBoxAdapter),
34+
), findsOne);
35+
36+
expect(find.descendant(
37+
of: customScrollViewFinder,
38+
matching: find.widgetWithIcon(SliverFillRemaining, Icons.sunny),
39+
), findsOne);
40+
41+
expect(find.descendant(
42+
of: customScrollViewFinder,
43+
matching: find.byType(GlowingOverscrollIndicator),
44+
), findsOne);
45+
46+
// Check if GlowingOverscrollIndicator starts just after the SliverAppBar.
47+
final RenderBox overscrollIndicator = tester.renderObject<RenderBox>(
48+
find.descendant(
49+
of: customScrollViewFinder,
50+
matching: find.byType(GlowingOverscrollIndicator),
51+
),
52+
);
53+
final RenderSliver sliverAppBar = tester.renderObject<RenderSliver>(
54+
find.widgetWithText(SliverAppBar, 'Custom NestedScrollViews'),
55+
);
56+
final Matrix4 transform = overscrollIndicator.getTransformTo(sliverAppBar);
57+
final Offset? offset = MatrixUtils.getAsTranslation(transform);
58+
expect(offset?.dy, sliverAppBar.geometry?.paintExtent);
59+
});
60+
}

0 commit comments

Comments
 (0)