blob: 1d46c128307ec9edb04061bdf100c797b683244c [file] [log] [blame]
// Copyright 2017 The Chromium 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/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
class Leaf extends StatefulWidget {
const Leaf({ Key key, this.child }) : super(key: key);
final Widget child;
@override
_LeafState createState() => new _LeafState();
}
class _LeafState extends State<Leaf> {
bool _keepAlive = false;
KeepAliveHandle _handle;
@override
void deactivate() {
_handle?.release();
_handle = null;
super.deactivate();
}
void setKeepAlive(bool value) {
_keepAlive = value;
if (_keepAlive) {
if (_handle == null) {
_handle = new KeepAliveHandle();
new KeepAliveNotification(_handle).dispatch(context);
}
} else {
_handle?.release();
_handle = null;
}
}
@override
Widget build(BuildContext context) {
if (_keepAlive && _handle == null) {
_handle = new KeepAliveHandle();
new KeepAliveNotification(_handle).dispatch(context);
}
return widget.child;
}
}
List<Widget> generateList(Widget child, { @required bool impliedMode }) {
return new List<Widget>.generate(
100,
(int index) {
final Widget result = new Leaf(
key: new GlobalObjectKey<_LeafState>(index),
child: child,
);
if (impliedMode)
return result;
return new AutomaticKeepAlive(child: result);
},
growable: false,
);
}
void tests({ @required bool impliedMode }) {
testWidgets('AutomaticKeepAlive with ListView with itemExtent', (WidgetTester tester) async {
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.ltr,
child: new ListView(
addAutomaticKeepAlives: impliedMode,
addRepaintBoundaries: impliedMode,
itemExtent: 12.3, // about 50 widgets visible
cacheExtent: 0.0,
children: generateList(const Placeholder(), impliedMode: impliedMode),
),
),
);
expect(find.byKey(const GlobalObjectKey<_LeafState>(3)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(30)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(59), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(60), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(61), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(90), skipOffstage: false), findsNothing);
await tester.drag(find.byType(ListView), const Offset(0.0, -300.0)); // about 25 widgets' worth
await tester.pump();
expect(find.byKey(const GlobalObjectKey<_LeafState>(3), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(30)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(59)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(60)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(61)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(90), skipOffstage: false), findsNothing);
const GlobalObjectKey<_LeafState>(60).currentState.setKeepAlive(true);
await tester.drag(find.byType(ListView), const Offset(0.0, 300.0)); // back to top
await tester.pump();
expect(find.byKey(const GlobalObjectKey<_LeafState>(3)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(30)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(59), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(60), skipOffstage: false), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(60)), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(61), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(90), skipOffstage: false), findsNothing);
const GlobalObjectKey<_LeafState>(60).currentState.setKeepAlive(false);
await tester.pump();
expect(find.byKey(const GlobalObjectKey<_LeafState>(3)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(30)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(59), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(60), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(61), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(90), skipOffstage: false), findsNothing);
});
testWidgets('AutomaticKeepAlive with ListView without itemExtent', (WidgetTester tester) async {
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.ltr,
child: new ListView(
addAutomaticKeepAlives: impliedMode,
addRepaintBoundaries: impliedMode,
cacheExtent: 0.0,
children: generateList(
new Container(height: 12.3, child: const Placeholder()), // about 50 widgets visible
impliedMode: impliedMode,
),
),
),
);
expect(find.byKey(const GlobalObjectKey<_LeafState>(3)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(30)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(59), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(60), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(61), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(90), skipOffstage: false), findsNothing);
await tester.drag(find.byType(ListView), const Offset(0.0, -300.0)); // about 25 widgets' worth
await tester.pump();
expect(find.byKey(const GlobalObjectKey<_LeafState>(3), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(30)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(59)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(60)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(61)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(90), skipOffstage: false), findsNothing);
const GlobalObjectKey<_LeafState>(60).currentState.setKeepAlive(true);
await tester.drag(find.byType(ListView), const Offset(0.0, 300.0)); // back to top
await tester.pump();
expect(find.byKey(const GlobalObjectKey<_LeafState>(3)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(30)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(59), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(60), skipOffstage: false), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(60)), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(61), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(90), skipOffstage: false), findsNothing);
const GlobalObjectKey<_LeafState>(60).currentState.setKeepAlive(false);
await tester.pump();
expect(find.byKey(const GlobalObjectKey<_LeafState>(3)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(30)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(59), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(60), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(61), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(90), skipOffstage: false), findsNothing);
});
testWidgets('AutomaticKeepAlive with GridView', (WidgetTester tester) async {
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.ltr,
child: new GridView.count(
addAutomaticKeepAlives: impliedMode,
addRepaintBoundaries: impliedMode,
crossAxisCount: 2,
childAspectRatio: 400.0 / 24.6, // about 50 widgets visible
cacheExtent: 0.0,
children: generateList(
new Container(child: const Placeholder()),
impliedMode: impliedMode,
),
),
),
);
expect(find.byKey(const GlobalObjectKey<_LeafState>(3)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(30)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(59), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(60), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(61), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(90), skipOffstage: false), findsNothing);
await tester.drag(find.byType(GridView), const Offset(0.0, -300.0)); // about 25 widgets' worth
await tester.pump();
expect(find.byKey(const GlobalObjectKey<_LeafState>(3), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(30)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(59)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(60)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(61)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(90), skipOffstage: false), findsNothing);
const GlobalObjectKey<_LeafState>(60).currentState.setKeepAlive(true);
await tester.drag(find.byType(GridView), const Offset(0.0, 300.0)); // back to top
await tester.pump();
expect(find.byKey(const GlobalObjectKey<_LeafState>(3)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(30)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(59), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(60), skipOffstage: false), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(60)), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(61), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(90), skipOffstage: false), findsNothing);
const GlobalObjectKey<_LeafState>(60).currentState.setKeepAlive(false);
await tester.pump();
expect(find.byKey(const GlobalObjectKey<_LeafState>(3)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(30)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(59), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(60), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(61), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(90), skipOffstage: false), findsNothing);
});
}
void main() {
group('Explicit automatic keep-alive', () { tests(impliedMode: false); });
group('Implied automatic keep-alive', () { tests(impliedMode: true); });
testWidgets('AutomaticKeepAlive double', (WidgetTester tester) async {
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.ltr,
child: new ListView(
addAutomaticKeepAlives: false,
addRepaintBoundaries: false,
cacheExtent: 0.0,
children: <Widget>[
new AutomaticKeepAlive(
child: new Container(
height: 400.0,
child: new Stack(children: const <Widget>[
const Leaf(key: const GlobalObjectKey<_LeafState>(0), child: const Placeholder()),
const Leaf(key: const GlobalObjectKey<_LeafState>(1), child: const Placeholder()),
]),
),
),
new AutomaticKeepAlive(
child: new Container(
key: const GlobalObjectKey<_LeafState>(2),
height: 400.0,
),
),
new AutomaticKeepAlive(
child: new Container(
key: const GlobalObjectKey<_LeafState>(3),
height: 400.0,
),
),
],
),
),
);
expect(find.byKey(const GlobalObjectKey<_LeafState>(0)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(1)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(2)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(3), skipOffstage: false), findsNothing);
await tester.drag(find.byType(ListView), const Offset(0.0, -1000.0)); // move to bottom
await tester.pump();
expect(find.byKey(const GlobalObjectKey<_LeafState>(0), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(1), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(2)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(3)), findsOneWidget);
await tester.drag(find.byType(ListView), const Offset(0.0, 1000.0)); // move to top
await tester.pump();
expect(find.byKey(const GlobalObjectKey<_LeafState>(0)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(1)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(2)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(3), skipOffstage: false), findsNothing);
const GlobalObjectKey<_LeafState>(0).currentState.setKeepAlive(true);
await tester.drag(find.byType(ListView), const Offset(0.0, -1000.0)); // move to bottom
await tester.pump();
expect(find.byKey(const GlobalObjectKey<_LeafState>(0), skipOffstage: false), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(1), skipOffstage: false), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(0)), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(1)), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(2)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(3)), findsOneWidget);
const GlobalObjectKey<_LeafState>(1).currentState.setKeepAlive(true);
await tester.pump();
expect(find.byKey(const GlobalObjectKey<_LeafState>(0), skipOffstage: false), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(1), skipOffstage: false), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(0)), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(1)), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(2)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(3)), findsOneWidget);
const GlobalObjectKey<_LeafState>(0).currentState.setKeepAlive(false);
await tester.pump();
expect(find.byKey(const GlobalObjectKey<_LeafState>(0), skipOffstage: false), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(1), skipOffstage: false), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(0)), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(1)), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(2)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(3)), findsOneWidget);
const GlobalObjectKey<_LeafState>(1).currentState.setKeepAlive(false);
await tester.pump();
expect(find.byKey(const GlobalObjectKey<_LeafState>(0), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(1), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(2)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(3)), findsOneWidget);
});
testWidgets('AutomaticKeepAlive double 2', (WidgetTester tester) async {
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.ltr,
child: new ListView(
addAutomaticKeepAlives: false,
addRepaintBoundaries: false,
cacheExtent: 0.0,
children: <Widget>[
new AutomaticKeepAlive(
child: new Container(
height: 400.0,
child: new Stack(children: const <Widget>[
const Leaf(key: const GlobalObjectKey<_LeafState>(0), child: const Placeholder()),
const Leaf(key: const GlobalObjectKey<_LeafState>(1), child: const Placeholder()),
]),
),
),
new AutomaticKeepAlive(
child: new Container(
height: 400.0,
child: new Stack(children: const <Widget>[
const Leaf(key: const GlobalObjectKey<_LeafState>(2), child: const Placeholder()),
const Leaf(key: const GlobalObjectKey<_LeafState>(3), child: const Placeholder()),
]),
),
),
new AutomaticKeepAlive(
child: new Container(
height: 400.0,
child: new Stack(children: const <Widget>[
const Leaf(key: const GlobalObjectKey<_LeafState>(4), child: const Placeholder()),
const Leaf(key: const GlobalObjectKey<_LeafState>(5), child: const Placeholder()),
]),
),
),
],
),
),
);
expect(find.byKey(const GlobalObjectKey<_LeafState>(0)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(1)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(2)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(3)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(4), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(5), skipOffstage: false), findsNothing);
const GlobalObjectKey<_LeafState>(0).currentState.setKeepAlive(true);
await tester.drag(find.byType(ListView), const Offset(0.0, -1000.0)); // move to bottom
await tester.pump();
expect(find.byKey(const GlobalObjectKey<_LeafState>(0), skipOffstage: false), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(1), skipOffstage: false), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(1)), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(0)), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(2)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(3)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(4)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(5)), findsOneWidget);
await tester.pumpWidget(new Directionality(
textDirection: TextDirection.ltr,
child: new ListView(
addAutomaticKeepAlives: false,
addRepaintBoundaries: false,
cacheExtent: 0.0,
children: <Widget>[
new AutomaticKeepAlive(
child: new Container(
height: 400.0,
child: new Stack(children: const <Widget>[
const Leaf(key: const GlobalObjectKey<_LeafState>(1), child: const Placeholder()),
]),
),
),
new AutomaticKeepAlive(
child: new Container(
height: 400.0,
child: new Stack(children: const <Widget>[
const Leaf(key: const GlobalObjectKey<_LeafState>(2), child: const Placeholder()),
const Leaf(key: const GlobalObjectKey<_LeafState>(3), child: const Placeholder()),
]),
),
),
new AutomaticKeepAlive(
child: new Container(
height: 400.0,
child: new Stack(children: const <Widget>[
const Leaf(key: const GlobalObjectKey<_LeafState>(4), child: const Placeholder()),
const Leaf(key: const GlobalObjectKey<_LeafState>(5), child: const Placeholder()),
const Leaf(key: const GlobalObjectKey<_LeafState>(0), child: const Placeholder()),
]),
),
),
],
),
));
await tester.pump(); // Sometimes AutomaticKeepAlive needs an extra pump to clean things up.
expect(find.byKey(const GlobalObjectKey<_LeafState>(1), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(2)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(3)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(4)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(5)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(0)), findsOneWidget);
await tester.drag(find.byType(ListView), const Offset(0.0, 1000.0)); // move to top
await tester.pump();
expect(find.byKey(const GlobalObjectKey<_LeafState>(1)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(2)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(3)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(4), skipOffstage: false), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(5), skipOffstage: false), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(0), skipOffstage: false), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(4)), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(5)), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(0)), findsNothing);
const GlobalObjectKey<_LeafState>(0).currentState.setKeepAlive(false);
await tester.pump();
expect(find.byKey(const GlobalObjectKey<_LeafState>(1)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(2)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(3)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(4), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(5), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(0), skipOffstage: false), findsNothing);
await tester.pumpWidget(new Directionality(
textDirection: TextDirection.ltr,
child: new ListView(
addAutomaticKeepAlives: false,
addRepaintBoundaries: false,
cacheExtent: 0.0,
children: <Widget>[
new AutomaticKeepAlive(
child: new Container(
height: 400.0,
child: new Stack(children: const <Widget>[
const Leaf(key: const GlobalObjectKey<_LeafState>(1), child: const Placeholder()),
const Leaf(key: const GlobalObjectKey<_LeafState>(2), child: const Placeholder()),
]),
),
),
new AutomaticKeepAlive(
child: new Container(
height: 400.0,
child: new Stack(children: const <Widget>[
]),
),
),
new AutomaticKeepAlive(
child: new Container(
height: 400.0,
child: new Stack(children: const <Widget>[
const Leaf(key: const GlobalObjectKey<_LeafState>(3), child: const Placeholder()),
const Leaf(key: const GlobalObjectKey<_LeafState>(4), child: const Placeholder()),
const Leaf(key: const GlobalObjectKey<_LeafState>(5), child: const Placeholder()),
const Leaf(key: const GlobalObjectKey<_LeafState>(0), child: const Placeholder()),
]),
),
),
],
),
));
await tester.pump(); // Sometimes AutomaticKeepAlive needs an extra pump to clean things up.
expect(find.byKey(const GlobalObjectKey<_LeafState>(1)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(2)), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_LeafState>(3), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(4), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(5), skipOffstage: false), findsNothing);
expect(find.byKey(const GlobalObjectKey<_LeafState>(0), skipOffstage: false), findsNothing);
});
testWidgets('AutomaticKeepAlive with keepAlive set to true before initState', (WidgetTester tester) async {
await tester.pumpWidget(new Directionality(
textDirection: TextDirection.ltr,
child: new ListView.builder(
itemCount: 50,
itemBuilder: (BuildContext context, int index){
if (index == 0){
return const _AlwaysKeepAlive(
key: const GlobalObjectKey<_AlwaysKeepAliveState>(0),
);
}
return new Container(
height: 44.0,
child: new Text('FooBar $index'),
);
},
),
));
expect(find.text('keep me alive'), findsOneWidget);
expect(find.text('FooBar 1'), findsOneWidget);
expect(find.text('FooBar 2'), findsOneWidget);
expect(find.byKey(const GlobalObjectKey<_AlwaysKeepAliveState>(0)), findsOneWidget);
await tester.drag(find.byType(ListView), const Offset(0.0, -1000.0)); // move to bottom
await tester.pump();
expect(find.byKey(const GlobalObjectKey<_AlwaysKeepAliveState>(0), skipOffstage: false), findsOneWidget);
expect(find.text('keep me alive', skipOffstage: false), findsOneWidget);
expect(find.text('FooBar 1'), findsNothing);
expect(find.text('FooBar 2'), findsNothing);
});
}
class _AlwaysKeepAlive extends StatefulWidget {
const _AlwaysKeepAlive({Key key}) : super(key: key);
@override
State<StatefulWidget> createState() => new _AlwaysKeepAliveState();
}
class _AlwaysKeepAliveState extends State<_AlwaysKeepAlive> with AutomaticKeepAliveClientMixin<_AlwaysKeepAlive> {
@override
bool get wantKeepAlive => true;
@override
Widget build(BuildContext context) {
super.build(context);
return new Container(
height: 48.0,
child: const Text('keep me alive'),
);
}
}