Unverified Commit 5c5ddd1f authored by chunhtai's avatar chunhtai Committed by GitHub

Revert "Fix 25807: implement move for sliver multibox widget (#29188)" (#31497)

This reverts commit 77ab0b83.
parent 981e922a
...@@ -1116,7 +1116,6 @@ class _TabBarViewState extends State<TabBarView> { ...@@ -1116,7 +1116,6 @@ class _TabBarViewState extends State<TabBarView> {
TabController _controller; TabController _controller;
PageController _pageController; PageController _pageController;
List<Widget> _children; List<Widget> _children;
List<Widget> _childrenWithKey;
int _currentIndex; int _currentIndex;
int _warpUnderwayCount = 0; int _warpUnderwayCount = 0;
...@@ -1158,7 +1157,7 @@ class _TabBarViewState extends State<TabBarView> { ...@@ -1158,7 +1157,7 @@ class _TabBarViewState extends State<TabBarView> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_updateChildren(); _children = widget.children;
} }
@override @override
...@@ -1175,7 +1174,7 @@ class _TabBarViewState extends State<TabBarView> { ...@@ -1175,7 +1174,7 @@ class _TabBarViewState extends State<TabBarView> {
if (widget.controller != oldWidget.controller) if (widget.controller != oldWidget.controller)
_updateTabController(); _updateTabController();
if (widget.children != oldWidget.children && _warpUnderwayCount == 0) if (widget.children != oldWidget.children && _warpUnderwayCount == 0)
_updateChildren(); _children = widget.children;
} }
@override @override
...@@ -1186,11 +1185,6 @@ class _TabBarViewState extends State<TabBarView> { ...@@ -1186,11 +1185,6 @@ class _TabBarViewState extends State<TabBarView> {
super.dispose(); super.dispose();
} }
void _updateChildren() {
_children = widget.children;
_childrenWithKey = KeyedSubtree.ensureUniqueKeysForList(widget.children);
}
void _handleTabControllerAnimationTick() { void _handleTabControllerAnimationTick() {
if (_warpUnderwayCount > 0 || !_controller.indexIsChanging) if (_warpUnderwayCount > 0 || !_controller.indexIsChanging)
return; // This widget is driving the controller's animation. return; // This widget is driving the controller's animation.
...@@ -1213,30 +1207,28 @@ class _TabBarViewState extends State<TabBarView> { ...@@ -1213,30 +1207,28 @@ class _TabBarViewState extends State<TabBarView> {
return _pageController.animateToPage(_currentIndex, duration: kTabScrollDuration, curve: Curves.ease); return _pageController.animateToPage(_currentIndex, duration: kTabScrollDuration, curve: Curves.ease);
assert((_currentIndex - previousIndex).abs() > 1); assert((_currentIndex - previousIndex).abs() > 1);
final int initialPage = _currentIndex > previousIndex int initialPage;
? _currentIndex - 1
: _currentIndex + 1;
final List<Widget> originalChildren = _childrenWithKey;
setState(() { setState(() {
_warpUnderwayCount += 1; _warpUnderwayCount += 1;
_children = List<Widget>.from(widget.children, growable: false);
_childrenWithKey = List<Widget>.from(_childrenWithKey, growable: false); if (_currentIndex > previousIndex) {
final Widget temp = _childrenWithKey[initialPage]; _children[_currentIndex - 1] = _children[previousIndex];
_childrenWithKey[initialPage] = _childrenWithKey[previousIndex]; initialPage = _currentIndex - 1;
_childrenWithKey[previousIndex] = temp; } else {
_children[_currentIndex + 1] = _children[previousIndex];
initialPage = _currentIndex + 1;
}
}); });
_pageController.jumpToPage(initialPage); _pageController.jumpToPage(initialPage);
await _pageController.animateToPage(_currentIndex, duration: kTabScrollDuration, curve: Curves.ease); await _pageController.animateToPage(_currentIndex, duration: kTabScrollDuration, curve: Curves.ease);
if (!mounted) if (!mounted)
return Future<void>.value(); return Future<void>.value();
setState(() { setState(() {
_warpUnderwayCount -= 1; _warpUnderwayCount -= 1;
if (widget.children != _children) { _children = widget.children;
_updateChildren();
} else {
_childrenWithKey = originalChildren;
}
}); });
} }
...@@ -1272,7 +1264,7 @@ class _TabBarViewState extends State<TabBarView> { ...@@ -1272,7 +1264,7 @@ class _TabBarViewState extends State<TabBarView> {
dragStartBehavior: widget.dragStartBehavior, dragStartBehavior: widget.dragStartBehavior,
controller: _pageController, controller: _pageController,
physics: widget.physics == null ? _kTabBarViewPhysics : _kTabBarViewPhysics.applyTo(widget.physics), physics: widget.physics == null ? _kTabBarViewPhysics : _kTabBarViewPhysics.applyTo(widget.physics),
children: _childrenWithKey, children: _children,
), ),
); );
} }
......
...@@ -85,8 +85,7 @@ abstract class RenderSliverBoxChildManager { ...@@ -85,8 +85,7 @@ abstract class RenderSliverBoxChildManager {
/// list). /// list).
int get childCount; int get childCount;
/// Called during [RenderSliverMultiBoxAdaptor.adoptChild] or /// Called during [RenderSliverMultiBoxAdaptor.adoptChild].
/// [RenderSliverMultiBoxAdaptor.move].
/// ///
/// Subclasses must ensure that the [SliverMultiBoxAdaptorParentData.index] /// Subclasses must ensure that the [SliverMultiBoxAdaptorParentData.index]
/// field of the child's [RenderObject.parentData] accurately reflects the /// field of the child's [RenderObject.parentData] accurately reflects the
...@@ -194,12 +193,7 @@ abstract class RenderSliverMultiBoxAdaptor extends RenderSliver ...@@ -194,12 +193,7 @@ abstract class RenderSliverMultiBoxAdaptor extends RenderSliver
RenderSliverMultiBoxAdaptor({ RenderSliverMultiBoxAdaptor({
@required RenderSliverBoxChildManager childManager, @required RenderSliverBoxChildManager childManager,
}) : assert(childManager != null), }) : assert(childManager != null),
_childManager = childManager { _childManager = childManager;
assert(() {
_debugDanglingKeepAlives = <RenderBox>[];
return true;
}());
}
@override @override
void setupParentData(RenderObject child) { void setupParentData(RenderObject child) {
...@@ -220,27 +214,6 @@ abstract class RenderSliverMultiBoxAdaptor extends RenderSliver ...@@ -220,27 +214,6 @@ abstract class RenderSliverMultiBoxAdaptor extends RenderSliver
/// The nodes being kept alive despite not being visible. /// The nodes being kept alive despite not being visible.
final Map<int, RenderBox> _keepAliveBucket = <int, RenderBox>{}; final Map<int, RenderBox> _keepAliveBucket = <int, RenderBox>{};
List<RenderBox> _debugDanglingKeepAlives;
/// Indicates whether integrity check is enabled.
///
/// Setting this property to true will immediately perform an integrity check.
///
/// The integrity check consists of:
///
/// 1. Verify that the children index in childList is in ascending order.
/// 2. Verify that there is no dangling keepalive child as the result of [move].
bool get debugChildIntegrityEnabled => _debugChildIntegrityEnabled;
bool _debugChildIntegrityEnabled = true;
set debugChildIntegrityEnabled(bool enabled) {
assert(enabled != null);
assert(() {
_debugChildIntegrityEnabled = enabled;
return _debugVerifyChildOrder() &&
(!_debugChildIntegrityEnabled || _debugDanglingKeepAlives.isEmpty);
}());
}
@override @override
void adoptChild(RenderObject child) { void adoptChild(RenderObject child) {
super.adoptChild(child); super.adoptChild(child);
...@@ -251,70 +224,21 @@ abstract class RenderSliverMultiBoxAdaptor extends RenderSliver ...@@ -251,70 +224,21 @@ abstract class RenderSliverMultiBoxAdaptor extends RenderSliver
bool _debugAssertChildListLocked() => childManager.debugAssertChildListLocked(); bool _debugAssertChildListLocked() => childManager.debugAssertChildListLocked();
/// Verify that the child list index is in strictly increasing order.
///
/// This has no effect in release builds.
bool _debugVerifyChildOrder(){
if (_debugChildIntegrityEnabled) {
RenderBox child = firstChild;
int index;
while (child != null) {
index = indexOf(child);
child = childAfter(child);
assert(child == null || indexOf(child) > index);
}
}
return true;
}
@override @override
void insert(RenderBox child, { RenderBox after }) { void insert(RenderBox child, { RenderBox after }) {
assert(!_keepAliveBucket.containsValue(child)); assert(!_keepAliveBucket.containsValue(child));
super.insert(child, after: after); super.insert(child, after: after);
assert(firstChild != null); assert(firstChild != null);
assert(_debugVerifyChildOrder()); assert(() {
} int index = indexOf(firstChild);
RenderBox child = childAfter(firstChild);
@override while (child != null) {
void move(RenderBox child, { RenderBox after }) { assert(indexOf(child) > index);
// There are two scenarios: index = indexOf(child);
// child = childAfter(child);
// 1. The child is not keptAlive.
// The child is in the childList maintained by ContainerRenderObjectMixin.
// We can call super.move and update parentData with the new slot.
//
// 2. The child is keptAlive.
// In this case, the child is no longer in the childList but might be stored in
// [_keepAliveBucket]. We need to update the location of the child in the bucket.
final SliverMultiBoxAdaptorParentData childParentData = child.parentData;
if (!childParentData.keptAlive) {
super.move(child, after: after);
childManager.didAdoptChild(child); // updates the slot in the parentData
// Its slot may change even if super.move does not change the position.
// In this case, we still want to mark as needs layout.
markNeedsLayout();
} else {
// If the child in the bucket is not current child, that means someone has
// already moved and replaced current child, and we cannot remove this child.
if (_keepAliveBucket[childParentData.index] == child) {
_keepAliveBucket.remove(childParentData.index);
} }
assert(() { return true;
_debugDanglingKeepAlives.remove(child); }());
return true;
}());
// Update the slot and reinsert back to _keepAliveBucket in the new slot.
childManager.didAdoptChild(child);
// If there is an existing child in the new slot, that mean that child will
// be moved to other index. In other cases, the existing child should have been
// removed by updateChild. Thus, it is ok to overwrite it.
assert(() {
if (_keepAliveBucket.containsKey(childParentData.index))
_debugDanglingKeepAlives.add(_keepAliveBucket[childParentData.index]);
return true;
}());
_keepAliveBucket[childParentData.index] = child;
}
} }
@override @override
...@@ -325,10 +249,6 @@ abstract class RenderSliverMultiBoxAdaptor extends RenderSliver ...@@ -325,10 +249,6 @@ abstract class RenderSliverMultiBoxAdaptor extends RenderSliver
return; return;
} }
assert(_keepAliveBucket[childParentData.index] == child); assert(_keepAliveBucket[childParentData.index] == child);
assert(() {
_debugDanglingKeepAlives.remove(child);
return true;
}());
_keepAliveBucket.remove(childParentData.index); _keepAliveBucket.remove(childParentData.index);
dropChild(child); dropChild(child);
} }
......
...@@ -149,13 +149,6 @@ abstract class GlobalKey<T extends State<StatefulWidget>> extends Key { ...@@ -149,13 +149,6 @@ abstract class GlobalKey<T extends State<StatefulWidget>> extends Key {
assert(() { assert(() {
assert(parent != null); assert(parent != null);
if (_debugReservations.containsKey(this) && _debugReservations[this] != parent) { if (_debugReservations.containsKey(this) && _debugReservations[this] != parent) {
// Reserving a new parent while the old parent is not attached is ok.
// This can happen when a renderObject detaches and re-attaches to rendering
// tree multiple times.
if (_debugReservations[this].renderObject?.attached == false) {
_debugReservations[this] = parent;
return true;
}
// It's possible for an element to get built multiple times in one // It's possible for an element to get built multiple times in one
// frame, in which case it'll reserve the same child's key multiple // frame, in which case it'll reserve the same child's key multiple
// times. We catch multiple children of one widget having the same key // times. We catch multiple children of one widget having the same key
......
...@@ -49,7 +49,6 @@ class StateMarkerState extends State<StateMarker> { ...@@ -49,7 +49,6 @@ class StateMarkerState extends State<StateMarker> {
} }
class AlwaysKeepAliveWidget extends StatefulWidget { class AlwaysKeepAliveWidget extends StatefulWidget {
const AlwaysKeepAliveWidget({ Key key}) : super(key: key);
static String text = 'AlwaysKeepAlive'; static String text = 'AlwaysKeepAlive';
@override @override
AlwaysKeepAliveState createState() => AlwaysKeepAliveState(); AlwaysKeepAliveState createState() => AlwaysKeepAliveState();
...@@ -1988,56 +1987,6 @@ void main() { ...@@ -1988,56 +1987,6 @@ void main() {
}); });
testWidgets('Skipping tabs with global key does not crash', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/24660
final List<String> tabs = <String>[
'Tab1',
'Tab2',
'Tab3',
'Tab4',
];
final TabController controller = TabController(
vsync: const TestVSync(),
length: tabs.length,
);
await tester.pumpWidget(
MaterialApp(
home: Align(
alignment: Alignment.topLeft,
child: SizedBox(
width: 300.0,
height: 200.0,
child: Scaffold(
appBar: AppBar(
title: const Text('tabs'),
bottom: TabBar(
controller: controller,
tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
),
),
body: TabBarView(
controller: controller,
children: <Widget>[
Text('1', key: GlobalKey()),
Text('2', key: GlobalKey()),
Text('3', key: GlobalKey()),
Text('4', key: GlobalKey()),
],
),
),
),
),
),
);
expect(find.text('1'), findsOneWidget);
expect(find.text('4'), findsNothing);
await tester.tap(find.text('Tab4'));
await tester.pumpAndSettle();
expect(controller.index, 3);
expect(find.text('4'), findsOneWidget);
expect(find.text('1'), findsNothing);
});
testWidgets('Skipping tabs with a KeepAlive child works', (WidgetTester tester) async { testWidgets('Skipping tabs with a KeepAlive child works', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/11895 // Regression test for https://github.com/flutter/flutter/issues/11895
final List<String> tabs = <String>[ final List<String> tabs = <String>[
...@@ -2069,7 +2018,7 @@ void main() { ...@@ -2069,7 +2018,7 @@ void main() {
body: TabBarView( body: TabBarView(
controller: controller, controller: controller,
children: <Widget>[ children: <Widget>[
AlwaysKeepAliveWidget(key: UniqueKey()), AlwaysKeepAliveWidget(),
const Text('2'), const Text('2'),
const Text('3'), const Text('3'),
const Text('4'), const Text('4'),
......
...@@ -9,10 +9,10 @@ import 'package:flutter/widgets.dart'; ...@@ -9,10 +9,10 @@ import 'package:flutter/widgets.dart';
void main() { void main() {
testWidgets('Sliver in a box', (WidgetTester tester) async { testWidgets('Sliver in a box', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
DecoratedBox( const DecoratedBox(
decoration: const BoxDecoration(), decoration: BoxDecoration(),
child: SliverList( child: SliverList(
delegate: SliverChildListDelegate(const <Widget>[]), delegate: SliverChildListDelegate(<Widget>[]),
), ),
), ),
); );
...@@ -21,9 +21,9 @@ void main() { ...@@ -21,9 +21,9 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
Row( Row(
children: <Widget>[ children: const <Widget>[
SliverList( SliverList(
delegate: SliverChildListDelegate(const <Widget>[]), delegate: SliverChildListDelegate(<Widget>[]),
), ),
], ],
), ),
......
...@@ -451,41 +451,6 @@ void main() { ...@@ -451,41 +451,6 @@ void main() {
expect(count, 2); expect(count, 2);
}); });
testWidgets('GlobalKey - dettach and re-attach child to different parents', (WidgetTester tester) async {
await tester.pumpWidget(Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: Container(
height: 100,
child: CustomScrollView(
controller: ScrollController(),
slivers: <Widget>[
SliverList(
delegate: SliverChildListDelegate(<Widget>[
Text('child', key: GlobalKey()),
]),
)
],
),
),
),
));
final SliverMultiBoxAdaptorElement element = tester.element(find.byType(SliverList));
Element childElement;
// Removing and recreating child with same Global Key should not trigger
// duplicate key error.
element.visitChildren((Element e) {
childElement = e;
});
element.removeChild(childElement.renderObject);
element.createChild(0, after: null);
element.visitChildren((Element e) {
childElement = e;
});
element.removeChild(childElement.renderObject);
element.createChild(0, after: null);
});
testWidgets('Defunct setState throws exception', (WidgetTester tester) async { testWidgets('Defunct setState throws exception', (WidgetTester tester) async {
StateSetter setState; StateSetter setState;
......
...@@ -22,12 +22,12 @@ void main() { ...@@ -22,12 +22,12 @@ void main() {
data: const MediaQueryData(), data: const MediaQueryData(),
child: CustomScrollView( child: CustomScrollView(
controller: controller, controller: controller,
slivers: <Widget>[ slivers: const <Widget>[
const SliverAppBar(floating: true, pinned: true, expandedHeight: 200.0, title: Text('A')), SliverAppBar(floating: true, pinned: true, expandedHeight: 200.0, title: Text('A')),
const SliverAppBar(primary: false, pinned: true, title: Text('B')), SliverAppBar(primary: false, pinned: true, title: Text('B')),
SliverList( SliverList(
delegate: SliverChildListDelegate( delegate: SliverChildListDelegate(
const <Widget>[ <Widget>[
Text('C'), Text('C'),
Text('D'), Text('D'),
SizedBox(height: 500.0), SizedBox(height: 500.0),
......
...@@ -203,9 +203,9 @@ void main() { ...@@ -203,9 +203,9 @@ void main() {
physics: const BouncingScrollPhysics(), physics: const BouncingScrollPhysics(),
slivers: <Widget>[ slivers: <Widget>[
SliverPersistentHeader(delegate: TestDelegate(), floating: true), SliverPersistentHeader(delegate: TestDelegate(), floating: true),
SliverList( const SliverList(
delegate: SliverChildListDelegate(<Widget>[ delegate: SliverChildListDelegate(<Widget>[
const SizedBox( SizedBox(
height: 300.0, height: 300.0,
child: Text('X'), child: Text('X'),
), ),
......
...@@ -258,9 +258,9 @@ void main() { ...@@ -258,9 +258,9 @@ void main() {
physics: const BouncingScrollPhysics(), physics: const BouncingScrollPhysics(),
slivers: <Widget>[ slivers: <Widget>[
SliverPersistentHeader(delegate: TestDelegate(), pinned: true), SliverPersistentHeader(delegate: TestDelegate(), pinned: true),
SliverList( const SliverList(
delegate: SliverChildListDelegate(<Widget>[ delegate: SliverChildListDelegate(<Widget>[
const SizedBox( SizedBox(
height: 300.0, height: 300.0,
child: Text('X'), child: Text('X'),
), ),
......
...@@ -75,38 +75,6 @@ void main() { ...@@ -75,38 +75,6 @@ void main() {
}); });
testWidgets('Sliver appbars - scrolling - overscroll gap is below header', (WidgetTester tester) async { testWidgets('Sliver appbars - scrolling - overscroll gap is below header', (WidgetTester tester) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: CustomScrollView(
physics: const BouncingScrollPhysics(),
slivers: <Widget>[
SliverPersistentHeader(delegate: TestDelegate()),
SliverList(
delegate: SliverChildListDelegate(<Widget>[
const SizedBox(
height: 300.0,
child: Text('X'),
),
]),
),
],
),
),
);
expect(tester.getTopLeft(find.byType(Container)), Offset.zero);
expect(tester.getTopLeft(find.text('X')), const Offset(0.0, 200.0));
final ScrollPosition position = tester.state<ScrollableState>(find.byType(Scrollable)).position;
position.jumpTo(-50.0);
await tester.pump();
expect(tester.getTopLeft(find.byType(Container)), Offset.zero);
expect(tester.getTopLeft(find.text('X')), const Offset(0.0, 250.0));
});
testWidgets('Sliver appbars const child delegate - scrolling - overscroll gap is below header', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -115,7 +83,7 @@ void main() { ...@@ -115,7 +83,7 @@ void main() {
slivers: <Widget>[ slivers: <Widget>[
SliverPersistentHeader(delegate: TestDelegate()), SliverPersistentHeader(delegate: TestDelegate()),
const SliverList( const SliverList(
delegate: SliverChildListDelegate.fixed(<Widget>[ delegate: SliverChildListDelegate(<Widget>[
SizedBox( SizedBox(
height: 300.0, height: 300.0,
child: Text('X'), child: Text('X'),
......
...@@ -9,28 +9,6 @@ import 'package:flutter/widgets.dart'; ...@@ -9,28 +9,6 @@ import 'package:flutter/widgets.dart';
import '../rendering/mock_canvas.dart'; import '../rendering/mock_canvas.dart';
Future<void> test(WidgetTester tester, double offset) { Future<void> test(WidgetTester tester, double offset) {
return tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Viewport(
offset: ViewportOffset.fixed(offset),
slivers: <Widget>[
SliverList(
delegate: SliverChildListDelegate(const <Widget>[
SizedBox(height: 400.0, child: Text('a')),
SizedBox(height: 400.0, child: Text('b')),
SizedBox(height: 400.0, child: Text('c')),
SizedBox(height: 400.0, child: Text('d')),
SizedBox(height: 400.0, child: Text('e')),
]),
),
],
),
),
);
}
Future<void> testWithConstChildDelegate(WidgetTester tester, double offset) {
return tester.pumpWidget( return tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -38,7 +16,7 @@ Future<void> testWithConstChildDelegate(WidgetTester tester, double offset) { ...@@ -38,7 +16,7 @@ Future<void> testWithConstChildDelegate(WidgetTester tester, double offset) {
offset: ViewportOffset.fixed(offset), offset: ViewportOffset.fixed(offset),
slivers: const <Widget>[ slivers: const <Widget>[
SliverList( SliverList(
delegate: SliverChildListDelegate.fixed(<Widget>[ delegate: SliverChildListDelegate(<Widget>[
SizedBox(height: 400.0, child: Text('a')), SizedBox(height: 400.0, child: Text('a')),
SizedBox(height: 400.0, child: Text('b')), SizedBox(height: 400.0, child: Text('b')),
SizedBox(height: 400.0, child: Text('c')), SizedBox(height: 400.0, child: Text('c')),
...@@ -98,39 +76,6 @@ void main() { ...@@ -98,39 +76,6 @@ void main() {
], 'ab'); ], 'ab');
}); });
testWidgets('Viewport+SliverBlock basic test with constant SliverChildListDelegate', (WidgetTester tester) async {
await testWithConstChildDelegate(tester, 0.0);
expect(tester.renderObject<RenderBox>(find.byType(Viewport)).size, equals(const Size(800.0, 600.0)));
verify(tester, <Offset>[
const Offset(0.0, 0.0),
const Offset(0.0, 400.0),
], 'ab');
await testWithConstChildDelegate(tester, 200.0);
verify(tester, <Offset>[
const Offset(0.0, -200.0),
const Offset(0.0, 200.0),
], 'ab');
await testWithConstChildDelegate(tester, 600.0);
verify(tester, <Offset>[
const Offset(0.0, -200.0),
const Offset(0.0, 200.0),
], 'bc');
await testWithConstChildDelegate(tester, 900.0);
verify(tester, <Offset>[
const Offset(0.0, -100.0),
const Offset(0.0, 300.0),
], 'cd');
await testWithConstChildDelegate(tester, 200.0);
verify(tester, <Offset>[
const Offset(0.0, -200.0),
const Offset(0.0, 200.0),
], 'ab');
});
testWidgets('Viewport with GlobalKey reparenting', (WidgetTester tester) async { testWidgets('Viewport with GlobalKey reparenting', (WidgetTester tester) async {
final Key key1 = GlobalKey(); final Key key1 = GlobalKey();
final ViewportOffset offset = ViewportOffset.zero(); final ViewportOffset offset = ViewportOffset.zero();
...@@ -205,9 +150,9 @@ void main() { ...@@ -205,9 +150,9 @@ void main() {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: Viewport( child: Viewport(
offset: offset, offset: offset,
slivers: <Widget>[ slivers: const <Widget>[
SliverList( SliverList(
delegate: SliverChildListDelegate(const <Widget>[ delegate: SliverChildListDelegate(<Widget>[
SizedBox(height: 251.0, child: Text('a')), SizedBox(height: 251.0, child: Text('a')),
SizedBox(height: 252.0, child: Text('b')), SizedBox(height: 252.0, child: Text('b')),
]), ]),
...@@ -316,9 +261,9 @@ void main() { ...@@ -316,9 +261,9 @@ void main() {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: Viewport( child: Viewport(
offset: ViewportOffset.zero(), offset: ViewportOffset.zero(),
slivers: <Widget>[ slivers: const <Widget>[
SliverList( SliverList(
delegate: SliverChildListDelegate(const <Widget>[ delegate: SliverChildListDelegate(<Widget>[
SizedBox(height: 400.0, child: Text('a')), SizedBox(height: 400.0, child: Text('a')),
]), ]),
), ),
...@@ -334,9 +279,9 @@ void main() { ...@@ -334,9 +279,9 @@ void main() {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: Viewport( child: Viewport(
offset: ViewportOffset.fixed(100.0), offset: ViewportOffset.fixed(100.0),
slivers: <Widget>[ slivers: const <Widget>[
SliverList( SliverList(
delegate: SliverChildListDelegate(const <Widget>[ delegate: SliverChildListDelegate(<Widget>[
SizedBox(height: 400.0, child: Text('a')), SizedBox(height: 400.0, child: Text('a')),
]), ]),
), ),
...@@ -352,9 +297,9 @@ void main() { ...@@ -352,9 +297,9 @@ void main() {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: Viewport( child: Viewport(
offset: ViewportOffset.fixed(100.0), offset: ViewportOffset.fixed(100.0),
slivers: <Widget>[ slivers: const <Widget>[
SliverList( SliverList(
delegate: SliverChildListDelegate(const <Widget>[ delegate: SliverChildListDelegate(<Widget>[
SizedBox(height: 4000.0, child: Text('a')), SizedBox(height: 4000.0, child: Text('a')),
]), ]),
), ),
...@@ -370,9 +315,9 @@ void main() { ...@@ -370,9 +315,9 @@ void main() {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: Viewport( child: Viewport(
offset: ViewportOffset.zero(), offset: ViewportOffset.zero(),
slivers: <Widget>[ slivers: const <Widget>[
SliverList( SliverList(
delegate: SliverChildListDelegate(const <Widget>[ delegate: SliverChildListDelegate(<Widget>[
SizedBox(height: 4000.0, child: Text('a')), SizedBox(height: 4000.0, child: Text('a')),
]), ]),
), ),
......
...@@ -206,8 +206,7 @@ void main() { ...@@ -206,8 +206,7 @@ void main() {
addRepaintBoundaries: false, addRepaintBoundaries: false,
addSemanticIndexes: false, addSemanticIndexes: false,
); );
final KeyedSubtree wrapped = builderThrowsDelegate.build(null, 0); expect(builderThrowsDelegate.build(null, 0), errorText);
expect(wrapped.child, errorText);
expect(tester.takeException(), 'builder'); expect(tester.takeException(), 'builder');
ErrorWidget.builder = oldBuilder; ErrorWidget.builder = oldBuilder;
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment