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
ff60778c
Unverified
Commit
ff60778c
authored
Jan 12, 2022
by
xubaolin
Committed by
GitHub
Jan 12, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[RenderListWheelViewport] Update content dimensions to prevent scroll offset changes (#96102)
parent
099aa029
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
95 additions
and
28 deletions
+95
-28
list_wheel_viewport.dart
packages/flutter/lib/src/rendering/list_wheel_viewport.dart
+14
-13
list_wheel_scroll_view.dart
packages/flutter/lib/src/widgets/list_wheel_scroll_view.dart
+17
-15
list_wheel_scroll_view_test.dart
...ges/flutter/test/widgets/list_wheel_scroll_view_test.dart
+64
-0
No files found.
packages/flutter/lib/src/rendering/list_wheel_viewport.dart
View file @
ff60778c
...
...
@@ -663,12 +663,10 @@ class RenderListWheelViewport
/// by [childManager].
@override
void
performLayout
()
{
final
BoxConstraints
childConstraints
=
constraints
.
copyWith
(
minHeight:
_itemExtent
,
maxHeight:
_itemExtent
,
minWidth:
0.0
,
);
// Apply the dimensions first in case it changes the scroll offset which
// determines what should be shown.
offset
.
applyViewportDimension
(
_viewportExtent
);
offset
.
applyContentDimensions
(
_minEstimatedScrollExtent
,
_maxEstimatedScrollExtent
);
// The height, in pixel, that children will be visible and might be laid out
// and painted.
...
...
@@ -680,7 +678,7 @@ class RenderListWheelViewport
visibleHeight
*=
2
;
final
double
firstVisibleOffset
=
offset
.
pixels
+
_itemExtent
/
2
-
visibleHeight
/
2
;
offset
.
pixels
+
_itemExtent
/
2
-
visibleHeight
/
2
;
final
double
lastVisibleOffset
=
firstVisibleOffset
+
visibleHeight
;
// The index range that we want to spawn children. We find indexes that
...
...
@@ -721,6 +719,11 @@ class RenderListWheelViewport
_destroyChild
(
firstChild
!);
}
final
BoxConstraints
childConstraints
=
constraints
.
copyWith
(
minHeight:
_itemExtent
,
maxHeight:
_itemExtent
,
minWidth:
0.0
,
);
// If there is no child at this stage, we add the first one that is in
// target range.
if
(
childCount
==
0
)
{
...
...
@@ -759,8 +762,6 @@ class RenderListWheelViewport
_layoutChild
(
lastChild
!,
childConstraints
,
++
currentLastIndex
);
}
offset
.
applyViewportDimension
(
_viewportExtent
);
// Applying content dimensions bases on how the childManager builds widgets:
// if it is available to provide a child just out of target range, then
// we don't know whether there's a limit yet, and set the dimension to the
...
...
@@ -770,16 +771,16 @@ class RenderListWheelViewport
?
_minEstimatedScrollExtent
:
indexToScrollOffset
(
targetFirstIndex
);
final
double
maxScrollExtent
=
childManager
.
childExistsAt
(
targetLastIndex
+
1
)
?
_maxEstimatedScrollExtent
:
indexToScrollOffset
(
targetLastIndex
);
?
_maxEstimatedScrollExtent
:
indexToScrollOffset
(
targetLastIndex
);
offset
.
applyContentDimensions
(
minScrollExtent
,
maxScrollExtent
);
}
bool
_shouldClipAtCurrentOffset
()
{
final
double
highestUntransformedPaintY
=
_getUntransformedPaintingCoordinateY
(
0.0
);
_getUntransformedPaintingCoordinateY
(
0.0
);
return
highestUntransformedPaintY
<
0.0
||
size
.
height
<
highestUntransformedPaintY
+
_maxEstimatedScrollExtent
+
_itemExtent
;
||
size
.
height
<
highestUntransformedPaintY
+
_maxEstimatedScrollExtent
+
_itemExtent
;
}
@override
...
...
packages/flutter/lib/src/widgets/list_wheel_scroll_view.dart
View file @
ff60778c
...
...
@@ -766,24 +766,26 @@ class _ListWheelScrollViewState extends State<ListWheelScrollView> {
}
}
bool
_handleScrollNotification
(
ScrollNotification
notification
)
{
if
(
notification
.
depth
==
0
&&
widget
.
onSelectedItemChanged
!=
null
&&
notification
is
ScrollUpdateNotification
&&
notification
.
metrics
is
FixedExtentMetrics
)
{
final
FixedExtentMetrics
metrics
=
notification
.
metrics
as
FixedExtentMetrics
;
final
int
currentItemIndex
=
metrics
.
itemIndex
;
if
(
currentItemIndex
!=
_lastReportedItemIndex
)
{
_lastReportedItemIndex
=
currentItemIndex
;
final
int
trueIndex
=
widget
.
childDelegate
.
trueIndexOf
(
currentItemIndex
);
widget
.
onSelectedItemChanged
!(
trueIndex
);
}
}
return
false
;
}
@override
Widget
build
(
BuildContext
context
)
{
return
NotificationListener
<
ScrollNotification
>(
onNotification:
(
ScrollNotification
notification
)
{
if
(
notification
.
depth
==
0
&&
widget
.
onSelectedItemChanged
!=
null
&&
notification
is
ScrollUpdateNotification
&&
notification
.
metrics
is
FixedExtentMetrics
)
{
final
FixedExtentMetrics
metrics
=
notification
.
metrics
as
FixedExtentMetrics
;
final
int
currentItemIndex
=
metrics
.
itemIndex
;
if
(
currentItemIndex
!=
_lastReportedItemIndex
)
{
_lastReportedItemIndex
=
currentItemIndex
;
final
int
trueIndex
=
widget
.
childDelegate
.
trueIndexOf
(
currentItemIndex
);
widget
.
onSelectedItemChanged
!(
trueIndex
);
}
}
return
false
;
},
onNotification:
_handleScrollNotification
,
child:
_FixedExtentScrollable
(
controller:
scrollController
,
physics:
widget
.
physics
,
...
...
packages/flutter/test/widgets/list_wheel_scroll_view_test.dart
View file @
ff60778c
...
...
@@ -230,6 +230,7 @@ void main() {
});
testWidgets
(
'child builder with lower and upper limits'
,
(
WidgetTester
tester
)
async
{
// Adjust the content dimensions at the end of `RenderListWheelViewport.performLayout()`
final
List
<
int
>
paintedChildren
=
<
int
>[];
final
FixedExtentScrollController
controller
=
...
...
@@ -285,6 +286,69 @@ void main() {
});
group
(
'layout'
,
()
{
// Regression test for https://github.com/flutter/flutter/issues/90953
testWidgets
(
'ListWheelScrollView childDelegate update test 2'
,
(
WidgetTester
tester
)
async
{
final
FixedExtentScrollController
controller
=
FixedExtentScrollController
(
initialItem:
2
);
Widget
buildFrame
(
int
childCount
)
{
return
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
ListWheelScrollView
.
useDelegate
(
controller:
controller
,
itemExtent:
400.0
,
onSelectedItemChanged:
(
_
)
{
},
childDelegate:
ListWheelChildBuilderDelegate
(
childCount:
childCount
,
builder:
(
BuildContext
context
,
int
index
)
{
return
SizedBox
(
width:
400.0
,
height:
400.0
,
child:
Text
(
index
.
toString
()),
);
},
),
),
);
}
await
tester
.
pumpWidget
(
buildFrame
(
5
));
expect
(
find
.
text
(
'0'
),
findsNothing
);
expect
(
tester
.
renderObject
(
find
.
text
(
'1'
)).
attached
,
true
);
expect
(
tester
.
renderObject
(
find
.
text
(
'2'
)).
attached
,
true
);
expect
(
tester
.
renderObject
(
find
.
text
(
'3'
)).
attached
,
true
);
expect
(
find
.
text
(
'4'
),
findsNothing
);
// Remove the last 3 items.
await
tester
.
pumpWidget
(
buildFrame
(
2
));
expect
(
tester
.
renderObject
(
find
.
text
(
'0'
)).
attached
,
true
);
expect
(
tester
.
renderObject
(
find
.
text
(
'1'
)).
attached
,
true
);
expect
(
find
.
text
(
'3'
),
findsNothing
);
// Add 3 items at the end.
await
tester
.
pumpWidget
(
buildFrame
(
5
));
expect
(
tester
.
renderObject
(
find
.
text
(
'0'
)).
attached
,
true
);
expect
(
tester
.
renderObject
(
find
.
text
(
'1'
)).
attached
,
true
);
expect
(
tester
.
renderObject
(
find
.
text
(
'2'
)).
attached
,
true
);
expect
(
find
.
text
(
'3'
),
findsNothing
);
expect
(
find
.
text
(
'4'
),
findsNothing
);
// Scroll to the last item.
final
TestGesture
scrollGesture
=
await
tester
.
startGesture
(
const
Offset
(
10.0
,
10.0
));
await
scrollGesture
.
moveBy
(
const
Offset
(
0.0
,
-
1200.0
));
await
tester
.
pump
();
expect
(
find
.
text
(
'0'
),
findsNothing
);
expect
(
find
.
text
(
'1'
),
findsNothing
);
expect
(
find
.
text
(
'2'
),
findsNothing
);
expect
(
tester
.
renderObject
(
find
.
text
(
'3'
)).
attached
,
true
);
expect
(
tester
.
renderObject
(
find
.
text
(
'4'
)).
attached
,
true
);
// Remove the last 3 items.
await
tester
.
pumpWidget
(
buildFrame
(
2
));
expect
(
tester
.
renderObject
(
find
.
text
(
'0'
)).
attached
,
true
);
expect
(
tester
.
renderObject
(
find
.
text
(
'1'
)).
attached
,
true
);
expect
(
find
.
text
(
'3'
),
findsNothing
);
});
// Regression test for https://github.com/flutter/flutter/issues/58144
testWidgets
(
'ListWheelScrollView childDelegate update test'
,
(
WidgetTester
tester
)
async
{
final
FixedExtentScrollController
controller
=
FixedExtentScrollController
();
...
...
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