Fix GlowingOverscrollIndicator examples (#155203)

Part of https://github.com/flutter/flutter/issues/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.
This commit is contained in:
miechoo 2024-10-30 21:50:00 +01:00 committed by GitHub
parent bb08ec9a03
commit 2d2ebbe263
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 247 additions and 16 deletions

View File

@ -321,6 +321,4 @@ final Set<String> _knownMissingTests = <String>{
'examples/api/test/widgets/interactive_viewer/interactive_viewer.constrained.0_test.dart',
'examples/api/test/widgets/interactive_viewer/interactive_viewer.transformation_controller.0_test.dart',
'examples/api/test/widgets/notification_listener/notification.0_test.dart',
'examples/api/test/widgets/overscroll_indicator/glowing_overscroll_indicator.1_test.dart',
'examples/api/test/widgets/overscroll_indicator/glowing_overscroll_indicator.0_test.dart',
};

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
/// Flutter code sample for [GlowingOverscrollIndicator].
@ -14,6 +15,8 @@ class GlowingOverscrollIndicatorExampleApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
scrollBehavior: const AlwaysGlow(),
theme: ThemeData(colorSchemeSeed: Colors.amber),
home: Scaffold(
appBar: AppBar(title: const Text('GlowingOverscrollIndicator Sample')),
body: const GlowingOverscrollIndicatorExample(),
@ -22,12 +25,37 @@ class GlowingOverscrollIndicatorExampleApp extends StatelessWidget {
}
}
const Set<PointerDeviceKind> allPointers = <PointerDeviceKind>{...PointerDeviceKind.values};
// Passing this class into the MaterialApp constructor ensures that a
// GlowingOverscrollIndicator is created, regardless of the target platform.
class AlwaysGlow extends MaterialScrollBehavior {
const AlwaysGlow();
@override
Set<PointerDeviceKind> get dragDevices => allPointers;
@override
Widget buildOverscrollIndicator(
BuildContext context,
Widget child,
ScrollableDetails details,
) {
return GlowingOverscrollIndicator(
axisDirection: details.direction,
color: Colors.amberAccent,
child: child,
);
}
}
class GlowingOverscrollIndicatorExample extends StatelessWidget {
const GlowingOverscrollIndicatorExample({super.key});
@override
Widget build(BuildContext context) {
final double leadingPaintOffset = MediaQuery.of(context).padding.top + AppBar().preferredSize.height;
final double leadingPaintOffset = MediaQuery.paddingOf(context).top + kToolbarHeight;
return NotificationListener<OverscrollIndicatorNotification>(
onNotification: (OverscrollIndicatorNotification notification) {
if (notification.leading) {
@ -35,17 +63,33 @@ class GlowingOverscrollIndicatorExample extends StatelessWidget {
}
return false;
},
child: CustomScrollView(
child: const CustomScrollView(
slivers: <Widget>[
const SliverAppBar(title: Text('Custom PaintOffset')),
SliverAppBar(title: Text('Custom PaintOffset')),
SliverToBoxAdapter(
child: Container(
child: DefaultTextStyle(
style: TextStyle(
color: Colors.amberAccent,
height: 100,
child: const Center(child: Text('Glow all day!')),
fontSize: 24,
fontWeight: FontWeight.w600,
),
child: ColoredBox(
color: Colors.grey,
child: SizedBox(
width: double.infinity,
height: 80,
child: Center(child: Text('Glow all day!')),
),
),
),
),
SliverFillRemaining(
child: Icon(
Icons.sunny,
color: Colors.amberAccent,
size: 128,
),
),
const SliverFillRemaining(child: FlutterLogo()),
],
),
);

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
/// Flutter code sample for [GlowingOverscrollIndicator].
@ -14,6 +15,8 @@ class GlowingOverscrollIndicatorExampleApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
scrollBehavior: const AlwaysGlow(),
theme: ThemeData(colorSchemeSeed: Colors.amber),
home: Scaffold(
appBar: AppBar(title: const Text('GlowingOverscrollIndicator Sample')),
body: const GlowingOverscrollIndicatorExample(),
@ -22,6 +25,31 @@ class GlowingOverscrollIndicatorExampleApp extends StatelessWidget {
}
}
const Set<PointerDeviceKind> allPointers = <PointerDeviceKind>{...PointerDeviceKind.values};
// Passing this class into the MaterialApp constructor ensures that a
// GlowingOverscrollIndicator is created, regardless of the target platform.
class AlwaysGlow extends MaterialScrollBehavior {
const AlwaysGlow();
@override
Set<PointerDeviceKind> get dragDevices => allPointers;
@override
Widget buildOverscrollIndicator(
BuildContext context,
Widget child,
ScrollableDetails details,
) {
return GlowingOverscrollIndicator(
axisDirection: details.direction,
color: Colors.amberAccent,
child: child,
);
}
}
class GlowingOverscrollIndicatorExample extends StatelessWidget {
const GlowingOverscrollIndicatorExample({super.key});
@ -33,16 +61,32 @@ class GlowingOverscrollIndicatorExample extends StatelessWidget {
SliverAppBar(title: Text('Custom NestedScrollViews')),
];
},
body: CustomScrollView(
body: const CustomScrollView(
slivers: <Widget>[
SliverToBoxAdapter(
child: Container(
child: DefaultTextStyle(
style: TextStyle(
color: Colors.amberAccent,
height: 100,
child: const Center(child: Text('Glow all day!')),
fontSize: 24,
fontWeight: FontWeight.w600,
),
child: ColoredBox(
color: Colors.grey,
child: SizedBox(
width: double.infinity,
height: 80,
child: Center(child: Text('Glow all day!')),
),
),
),
),
SliverFillRemaining(
child: Icon(
Icons.sunny,
color: Colors.amberAccent,
size: 128,
),
),
const SliverFillRemaining(child: FlutterLogo()),
],
),
);

View File

@ -0,0 +1,85 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_api_samples/widgets/overscroll_indicator/glowing_overscroll_indicator.0.dart' as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Displays widget tree when the example app is run', (WidgetTester tester) async {
await tester.pumpWidget(const example.GlowingOverscrollIndicatorExampleApp());
expect(find.descendant(
of: find.byType(Scaffold),
matching: find.widgetWithText(AppBar, 'GlowingOverscrollIndicator Sample'),
), findsOne);
final Finder customScrollViewFinder = find.byType(CustomScrollView);
final Finder sliverAppBarFinder = find.descendant(
of: customScrollViewFinder,
matching: find.widgetWithText(SliverAppBar, 'Custom PaintOffset'),
);
expect(sliverAppBarFinder, findsOne);
expect(find.descendant(
of: customScrollViewFinder,
matching: find.widgetWithText(Center, 'Glow all day!'),
), findsOne);
expect(find.descendant(
of: customScrollViewFinder,
matching: find.byType(SliverToBoxAdapter),
), findsOne);
expect(find.descendant(
of: customScrollViewFinder,
matching: find.widgetWithIcon(SliverFillRemaining, Icons.sunny),
), findsOne);
expect(find.descendant(
of: customScrollViewFinder,
matching: find.byType(GlowingOverscrollIndicator),
), findsOne);
// Check if GlowingOverscrollIndicator overlays the SliverAppBar.
final RenderBox overscrollIndicator = tester.renderObject<RenderBox>(
find.descendant(
of: customScrollViewFinder,
matching: find.byType(GlowingOverscrollIndicator),
),
);
final RenderSliver sliverAppBar = tester.renderObject<RenderSliver>(sliverAppBarFinder);
final Matrix4 transform = overscrollIndicator.getTransformTo(sliverAppBar);
final Offset? offset = MatrixUtils.getAsTranslation(transform);
expect(offset?.dy, 0);
});
testWidgets('Triggers a notification listener when the screen is dragged', (WidgetTester tester) async {
bool overscrollNotified = false;
double leadingPaintOffset = 0.0;
await tester.pumpWidget(
NotificationListener<OverscrollIndicatorNotification>(
onNotification: (OverscrollIndicatorNotification notification) {
overscrollNotified = true;
leadingPaintOffset = notification.paintOffset;
return false;
},
child: const example.GlowingOverscrollIndicatorExampleApp(),
),
);
expect(leadingPaintOffset, 0);
expect(overscrollNotified, isFalse);
final BuildContext context = tester.element(find.byType(MaterialApp));
await tester.drag(find.byType(CustomScrollView), const Offset(0, 500));
await tester.pump();
expect(leadingPaintOffset, MediaQuery.paddingOf(context).top + kToolbarHeight);
expect(overscrollNotified, isTrue);
});
}

View File

@ -0,0 +1,60 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_api_samples/widgets/overscroll_indicator/glowing_overscroll_indicator.1.dart' as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Displays widget tree when the example app is run', (WidgetTester tester) async {
await tester.pumpWidget(const example.GlowingOverscrollIndicatorExampleApp());
expect(find.descendant(
of: find.byType(Scaffold),
matching: find.widgetWithText(AppBar, 'GlowingOverscrollIndicator Sample'),
), findsOne);
expect(find.descendant(
of: find.byType(NestedScrollView),
matching: find.widgetWithText(SliverAppBar, 'Custom NestedScrollViews'),
), findsOne);
expect(find.descendant(
of: find.byType(NestedScrollView),
matching: find.widgetWithText(Center, 'Glow all day!'),
), findsOne);
final Finder customScrollViewFinder = find.byType(CustomScrollView);
expect(find.descendant(
of: customScrollViewFinder,
matching: find.byType(SliverToBoxAdapter),
), findsOne);
expect(find.descendant(
of: customScrollViewFinder,
matching: find.widgetWithIcon(SliverFillRemaining, Icons.sunny),
), findsOne);
expect(find.descendant(
of: customScrollViewFinder,
matching: find.byType(GlowingOverscrollIndicator),
), findsOne);
// Check if GlowingOverscrollIndicator starts just after the SliverAppBar.
final RenderBox overscrollIndicator = tester.renderObject<RenderBox>(
find.descendant(
of: customScrollViewFinder,
matching: find.byType(GlowingOverscrollIndicator),
),
);
final RenderSliver sliverAppBar = tester.renderObject<RenderSliver>(
find.widgetWithText(SliverAppBar, 'Custom NestedScrollViews'),
);
final Matrix4 transform = overscrollIndicator.getTransformTo(sliverAppBar);
final Offset? offset = MatrixUtils.getAsTranslation(transform);
expect(offset?.dy, sliverAppBar.geometry?.paintExtent);
});
}