Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
1ba99b94
Unverified
Commit
1ba99b94
authored
Apr 19, 2018
by
Michael Goderbauer
Committed by
GitHub
Apr 19, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
SliverList works with changing children that are keyed (#16724)
Fixes #14590.
parent
cf577881
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
195 additions
and
0 deletions
+195
-0
sliver.dart
packages/flutter/lib/src/widgets/sliver.dart
+14
-0
sliver_list_test.dart
packages/flutter/test/widgets/sliver_list_test.dart
+181
-0
No files found.
packages/flutter/lib/src/widgets/sliver.dart
View file @
1ba99b94
...
@@ -738,6 +738,20 @@ class SliverMultiBoxAdaptorElement extends RenderObjectElement implements Render
...
@@ -738,6 +738,20 @@ class SliverMultiBoxAdaptorElement extends RenderObjectElement implements Render
});
});
}
}
@override
Element
updateChild
(
Element
child
,
Widget
newWidget
,
dynamic
newSlot
)
{
final
SliverMultiBoxAdaptorParentData
oldParentData
=
child
?.
renderObject
?.
parentData
;
final
Element
newChild
=
super
.
updateChild
(
child
,
newWidget
,
newSlot
);
final
SliverMultiBoxAdaptorParentData
newParentData
=
newChild
?.
renderObject
?.
parentData
;
// Preserve the old layoutOffset if the renderObject was swapped out.
if
(
oldParentData
!=
newParentData
&&
oldParentData
!=
null
&&
newParentData
!=
null
)
{
newParentData
.
layoutOffset
=
oldParentData
.
layoutOffset
;
}
return
newChild
;
}
@override
@override
void
forgetChild
(
Element
child
)
{
void
forgetChild
(
Element
child
)
{
assert
(
child
!=
null
);
assert
(
child
!=
null
);
...
...
packages/flutter/test/widgets/sliver_list_test.dart
0 → 100644
View file @
1ba99b94
// Copyright 2018 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_test/flutter_test.dart'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/widgets.dart'
;
void
main
(
)
{
testWidgets
(
'SliverList reverse children (with keys)'
,
(
WidgetTester
tester
)
async
{
final
List
<
int
>
items
=
new
List
<
int
>.
generate
(
20
,
(
int
i
)
=>
i
);
const
double
itemHeight
=
300.0
;
const
double
viewportHeight
=
500.0
;
const
double
scrollPosition
=
18
*
itemHeight
;
final
ScrollController
controller
=
new
ScrollController
(
initialScrollOffset:
scrollPosition
);
await
tester
.
pumpWidget
(
_buildSliverList
(
items:
items
,
controller:
controller
,
itemHeight:
itemHeight
,
viewportHeight:
viewportHeight
,
));
await
tester
.
pumpAndSettle
();
expect
(
controller
.
offset
,
scrollPosition
);
expect
(
find
.
text
(
'Tile 0'
),
findsNothing
);
expect
(
find
.
text
(
'Tile 1'
),
findsNothing
);
expect
(
find
.
text
(
'Tile 18'
),
findsOneWidget
);
expect
(
find
.
text
(
'Tile 19'
),
findsOneWidget
);
await
tester
.
pumpWidget
(
_buildSliverList
(
items:
items
.
reversed
.
toList
(),
controller:
controller
,
itemHeight:
itemHeight
,
viewportHeight:
viewportHeight
,
));
final
int
frames
=
await
tester
.
pumpAndSettle
();
expect
(
frames
,
1
);
// ensures that there is no (animated) bouncing of the scrollable
expect
(
controller
.
offset
,
scrollPosition
);
expect
(
find
.
text
(
'Tile 19'
),
findsNothing
);
expect
(
find
.
text
(
'Tile 18'
),
findsNothing
);
expect
(
find
.
text
(
'Tile 1'
),
findsOneWidget
);
expect
(
find
.
text
(
'Tile 0'
),
findsOneWidget
);
controller
.
jumpTo
(
0.0
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
offset
,
0.0
);
expect
(
find
.
text
(
'Tile 19'
),
findsOneWidget
);
expect
(
find
.
text
(
'Tile 18'
),
findsOneWidget
);
expect
(
find
.
text
(
'Tile 1'
),
findsNothing
);
expect
(
find
.
text
(
'Tile 0'
),
findsNothing
);
});
testWidgets
(
'SliverList replace children (with keys)'
,
(
WidgetTester
tester
)
async
{
final
List
<
int
>
items
=
new
List
<
int
>.
generate
(
20
,
(
int
i
)
=>
i
);
const
double
itemHeight
=
300.0
;
const
double
viewportHeight
=
500.0
;
const
double
scrollPosition
=
18
*
itemHeight
;
final
ScrollController
controller
=
new
ScrollController
(
initialScrollOffset:
scrollPosition
);
await
tester
.
pumpWidget
(
_buildSliverList
(
items:
items
,
controller:
controller
,
itemHeight:
itemHeight
,
viewportHeight:
viewportHeight
,
));
await
tester
.
pumpAndSettle
();
expect
(
controller
.
offset
,
scrollPosition
);
expect
(
find
.
text
(
'Tile 0'
),
findsNothing
);
expect
(
find
.
text
(
'Tile 1'
),
findsNothing
);
expect
(
find
.
text
(
'Tile 18'
),
findsOneWidget
);
expect
(
find
.
text
(
'Tile 19'
),
findsOneWidget
);
await
tester
.
pumpWidget
(
_buildSliverList
(
items:
items
.
map
((
int
i
)
=>
i
+
100
).
toList
(),
controller:
controller
,
itemHeight:
itemHeight
,
viewportHeight:
viewportHeight
,
));
final
int
frames
=
await
tester
.
pumpAndSettle
();
expect
(
frames
,
1
);
// ensures that there is no (animated) bouncing of the scrollable
expect
(
controller
.
offset
,
scrollPosition
);
expect
(
find
.
text
(
'Tile 0'
),
findsNothing
);
expect
(
find
.
text
(
'Tile 1'
),
findsNothing
);
expect
(
find
.
text
(
'Tile 18'
),
findsNothing
);
expect
(
find
.
text
(
'Tile 19'
),
findsNothing
);
expect
(
find
.
text
(
'Tile 100'
),
findsNothing
);
expect
(
find
.
text
(
'Tile 101'
),
findsNothing
);
expect
(
find
.
text
(
'Tile 118'
),
findsOneWidget
);
expect
(
find
.
text
(
'Tile 119'
),
findsOneWidget
);
controller
.
jumpTo
(
0.0
);
await
tester
.
pumpAndSettle
();
expect
(
controller
.
offset
,
0.0
);
expect
(
find
.
text
(
'Tile 100'
),
findsOneWidget
);
expect
(
find
.
text
(
'Tile 101'
),
findsOneWidget
);
expect
(
find
.
text
(
'Tile 118'
),
findsNothing
);
expect
(
find
.
text
(
'Tile 119'
),
findsNothing
);
});
testWidgets
(
'SliverList replace with shorter children list (with keys)'
,
(
WidgetTester
tester
)
async
{
final
List
<
int
>
items
=
new
List
<
int
>.
generate
(
20
,
(
int
i
)
=>
i
);
const
double
itemHeight
=
300.0
;
const
double
viewportHeight
=
500.0
;
final
double
scrollPosition
=
items
.
length
*
itemHeight
-
viewportHeight
;
final
ScrollController
controller
=
new
ScrollController
(
initialScrollOffset:
scrollPosition
);
await
tester
.
pumpWidget
(
_buildSliverList
(
items:
items
,
controller:
controller
,
itemHeight:
itemHeight
,
viewportHeight:
viewportHeight
,
));
await
tester
.
pumpAndSettle
();
expect
(
controller
.
offset
,
scrollPosition
);
expect
(
find
.
text
(
'Tile 0'
),
findsNothing
);
expect
(
find
.
text
(
'Tile 1'
),
findsNothing
);
expect
(
find
.
text
(
'Tile 17'
),
findsNothing
);
expect
(
find
.
text
(
'Tile 18'
),
findsOneWidget
);
expect
(
find
.
text
(
'Tile 19'
),
findsOneWidget
);
await
tester
.
pumpWidget
(
_buildSliverList
(
items:
items
.
sublist
(
0
,
items
.
length
-
1
),
controller:
controller
,
itemHeight:
itemHeight
,
viewportHeight:
viewportHeight
,
));
final
int
frames
=
await
tester
.
pumpAndSettle
();
expect
(
frames
,
greaterThan
(
1
));
// ensure animation to bring tile17 into view
expect
(
controller
.
offset
,
scrollPosition
-
itemHeight
);
expect
(
find
.
text
(
'Tile 0'
),
findsNothing
);
expect
(
find
.
text
(
'Tile 1'
),
findsNothing
);
expect
(
find
.
text
(
'Tile 17'
),
findsOneWidget
);
expect
(
find
.
text
(
'Tile 18'
),
findsOneWidget
);
expect
(
find
.
text
(
'Tile 19'
),
findsNothing
);
});
}
Widget
_buildSliverList
(
{
List
<
int
>
items:
const
<
int
>[],
ScrollController
controller
,
double
itemHeight:
500.0
,
double
viewportHeight:
300.0
,
})
{
return
new
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
new
Center
(
child:
new
Container
(
height:
viewportHeight
,
child:
new
CustomScrollView
(
controller:
controller
,
slivers:
<
Widget
>[
new
SliverList
(
delegate:
new
SliverChildBuilderDelegate
(
(
BuildContext
context
,
int
i
)
{
return
new
Container
(
key:
new
ValueKey
<
int
>(
items
[
i
]),
height:
itemHeight
,
child:
new
Text
(
'Tile
${items[i]}
'
),
);
},
childCount:
items
.
length
,
),
),
],
),
),
),
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment