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
a3fe33af
Unverified
Commit
a3fe33af
authored
Aug 28, 2020
by
xubaolin
Committed by
GitHub
Aug 28, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
The OverscrollIndicator should not overflow the scrollable view's edge (#64239)
parent
8f370dff
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
122 additions
and
8 deletions
+122
-8
overscroll_indicator.dart
packages/flutter/lib/src/widgets/overscroll_indicator.dart
+8
-5
overscroll_indicator_test.dart
packages/flutter/test/widgets/overscroll_indicator_test.dart
+114
-3
No files found.
packages/flutter/lib/src/widgets/overscroll_indicator.dart
View file @
a3fe33af
...
...
@@ -253,9 +253,15 @@ class _GlowingOverscrollIndicatorState extends State<GlowingOverscrollIndicator>
// scroll, e.g. when scrolling in the opposite direction again to hide
// the glow. Otherwise, the glow would always stay in a fixed position,
// even if the top of the content already scrolled away.
_leadingController
.
_paintOffsetScrollPixels
=
-
notification
.
metrics
.
pixels
;
// For example (CustomScrollView with sliver before center), the scroll
// extent is [-200.0, 300.0], scroll in the opposite direction with 10.0 pixels
// before glow disappears, so the current pixels is -190.0,
// in this case, we should move the glow up 10.0 pixels and should not
// overflow the scrollable widget's edge. https://github.com/flutter/flutter/issues/64149.
_leadingController
.
_paintOffsetScrollPixels
=
-
math
.
min
(
notification
.
metrics
.
pixels
-
notification
.
metrics
.
minScrollExtent
,
_leadingController
.
_paintOffset
);
_trailingController
.
_paintOffsetScrollPixels
=
-(
notification
.
metrics
.
maxScrollExtent
-
notification
.
metrics
.
pixels
);
-
math
.
min
(
notification
.
metrics
.
maxScrollExtent
-
notification
.
metrics
.
pixels
,
_trailingController
.
_paintOffset
);
if
(
notification
is
OverscrollNotification
)
{
_GlowController
controller
;
...
...
@@ -269,9 +275,6 @@ class _GlowingOverscrollIndicatorState extends State<GlowingOverscrollIndicator>
final
bool
isLeading
=
controller
==
_leadingController
;
if
(
_lastNotificationType
!=
OverscrollNotification
)
{
final
OverscrollIndicatorNotification
confirmationNotification
=
OverscrollIndicatorNotification
(
leading:
isLeading
);
// It is possible that the scroll extent starts at non-zero.
if
(
isLeading
)
confirmationNotification
.
paintOffset
=
notification
.
metrics
.
minScrollExtent
;
confirmationNotification
.
dispatch
(
context
);
_accepted
[
isLeading
]
=
confirmationNotification
.
_accepted
;
if
(
_accepted
[
isLeading
])
{
...
...
packages/flutter/test/widgets/overscroll_indicator_test.dart
View file @
a3fe33af
...
...
@@ -362,7 +362,116 @@ void main() {
expect
(
painter
,
paints
..
save
()..
translate
(
y:
0.0
)..
scale
()..
circle
());
});
group
(
'Modify glow position'
,
()
{
testWidgets
(
'CustomScrollView overscroll indicator works well with [CustomScrollView.center] and [OverscrollIndicatorNotification.paintOffset]'
,
(
WidgetTester
tester
)
async
{
final
Key
centerKey
=
UniqueKey
();
await
tester
.
pumpWidget
(
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
ScrollConfiguration
(
behavior:
TestScrollBehavior2
(),
child:
NotificationListener
<
OverscrollIndicatorNotification
>(
onNotification:
(
OverscrollIndicatorNotification
notification
)
{
if
(
notification
.
leading
)
{
notification
.
paintOffset
=
50.0
;
}
return
false
;
},
child:
CustomScrollView
(
center:
centerKey
,
physics:
const
AlwaysScrollableScrollPhysics
(),
slivers:
<
Widget
>[
SliverList
(
delegate:
SliverChildBuilderDelegate
(
(
BuildContext
context
,
int
index
)
=>
Text
(
'First sliver
$index
'
,),
childCount:
2
,
),
),
SliverList
(
key:
centerKey
,
delegate:
SliverChildBuilderDelegate
(
(
BuildContext
context
,
int
index
)
=>
Text
(
'Second sliver
$index
'
,),
childCount:
5
,
),
),
],
),
),
),
),
);
expect
(
find
.
text
(
'First sliver 1'
),
findsNothing
);
await
slowDrag
(
tester
,
const
Offset
(
200.0
,
200.0
),
const
Offset
(
0.0
,
5.0
));
// offset will be magnified ten times
expect
(
find
.
text
(
'First sliver 1'
),
findsOneWidget
);
final
RenderObject
painter
=
tester
.
renderObject
(
find
.
byType
(
CustomPaint
));
// The OverscrollIndicator should respect the [OverscrollIndicatorNotification.paintOffset] setting.
expect
(
painter
,
paints
..
save
()..
translate
(
y:
50.0
)..
scale
()..
circle
());
});
testWidgets
(
'The OverscrollIndicator should not overflow the scrollable view edge'
,
(
WidgetTester
tester
)
async
{
// Regressing test for https://github.com/flutter/flutter/issues/64149
await
tester
.
pumpWidget
(
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
NotificationListener
<
OverscrollIndicatorNotification
>(
onNotification:
(
OverscrollIndicatorNotification
notification
)
{
notification
.
paintOffset
=
50.0
;
// both the leading and trailing indicator have a 50.0 pixels offset.
return
false
;
},
child:
const
CustomScrollView
(
slivers:
<
Widget
>[
SliverToBoxAdapter
(
child:
SizedBox
(
height:
2000.0
)),
],
),
),
),
);
final
RenderObject
painter
=
tester
.
renderObject
(
find
.
byType
(
CustomPaint
));
await
slowDrag
(
tester
,
const
Offset
(
200.0
,
200.0
),
const
Offset
(
0.0
,
5.0
));
expect
(
painter
,
paints
..
save
()..
translate
(
y:
50.0
)..
scale
()..
circle
());
// Reverse scroll (30 pixels), and the offset < notification.paintOffset.
await
tester
.
dragFrom
(
const
Offset
(
200.0
,
200.0
),
const
Offset
(
0.0
,
-
30.0
));
await
tester
.
pump
();
// The OverscrollIndicator should move with the CustomScrollView.
expect
(
painter
,
paints
..
save
()..
translate
(
y:
50.0
-
30.0
)..
scale
()..
circle
());
// Reverse scroll (30+20 pixels) and offset == notification.paintOffset.
await
tester
.
dragFrom
(
const
Offset
(
200.0
,
200.0
),
const
Offset
(
0.0
,
-
20.0
));
await
tester
.
pump
();
expect
(
painter
,
paints
..
save
()..
translate
(
y:
50.0
-
50.0
)..
scale
()..
circle
());
// Reverse scroll (30+20+10 pixels) and offset > notification.paintOffset.
await
tester
.
dragFrom
(
const
Offset
(
200.0
,
200.0
),
const
Offset
(
0.0
,
-
10.0
));
await
tester
.
pump
();
// The OverscrollIndicator should not overflow the CustomScrollView's edge.
expect
(
painter
,
paints
..
save
()..
translate
(
y:
50.0
-
50.0
)..
scale
()..
circle
());
await
tester
.
pumpAndSettle
();
// Finish the leading indicator.
// trigger the trailing indicator
await
slowDrag
(
tester
,
const
Offset
(
200.0
,
200.0
),
const
Offset
(
0.0
,
-
200.0
));
expect
(
painter
,
paints
..
scale
(
y:
-
1.0
)..
save
()..
translate
(
y:
50.0
)..
scale
()..
circle
());
// Reverse scroll (30 pixels), and the offset < notification.paintOffset.
await
tester
.
dragFrom
(
const
Offset
(
200.0
,
200.0
),
const
Offset
(
0.0
,
30.0
));
await
tester
.
pump
();
// The OverscrollIndicator should move with the CustomScrollView.
expect
(
painter
,
paints
..
scale
(
y:
-
1.0
)..
save
()..
translate
(
y:
50.0
-
30.0
)..
scale
()..
circle
());
// Reverse scroll (30+20 pixels) and offset == notification.paintOffset.
await
tester
.
dragFrom
(
const
Offset
(
200.0
,
200.0
),
const
Offset
(
0.0
,
20.0
));
await
tester
.
pump
();
expect
(
painter
,
paints
..
scale
(
y:
-
1.0
)..
save
()..
translate
(
y:
50.0
-
50.0
)..
scale
()..
circle
());
// Reverse scroll (30+20+10 pixels) and offset > notification.paintOffset.
await
tester
.
dragFrom
(
const
Offset
(
200.0
,
200.0
),
const
Offset
(
0.0
,
10.0
));
await
tester
.
pump
();
// The OverscrollIndicator should not overflow the CustomScrollView's edge.
expect
(
painter
,
paints
..
scale
(
y:
-
1.0
)..
save
()..
translate
(
y:
50.0
-
50.0
)..
scale
()..
circle
());
});
group
(
'[OverscrollIndicatorNotification.paintOffset] test'
,
()
{
testWidgets
(
'Leading'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
Directionality
(
...
...
@@ -384,11 +493,12 @@ void main() {
);
final
RenderObject
painter
=
tester
.
renderObject
(
find
.
byType
(
CustomPaint
));
await
slowDrag
(
tester
,
const
Offset
(
200.0
,
200.0
),
const
Offset
(
0.0
,
5.0
));
// The OverscrollIndicator should respect the [OverscrollIndicatorNotification.paintOffset] setting.
expect
(
painter
,
paints
..
save
()..
translate
(
y:
50.0
)..
scale
()..
circle
());
// Reverse scroll direction.
await
tester
.
dragFrom
(
const
Offset
(
200.0
,
200.0
),
const
Offset
(
0.0
,
-
30.0
));
await
tester
.
pump
();
// The
painter should follow the scroll direction
.
// The
OverscrollIndicator should move with the CustomScrollView
.
expect
(
painter
,
paints
..
save
()..
translate
(
y:
50.0
-
30.0
)..
scale
()..
circle
());
});
...
...
@@ -415,11 +525,12 @@ void main() {
await
tester
.
dragFrom
(
const
Offset
(
200.0
,
200.0
),
const
Offset
(
200.0
,
-
10000.0
));
await
tester
.
pump
();
await
slowDrag
(
tester
,
const
Offset
(
200.0
,
200.0
),
const
Offset
(
0.0
,
-
5.0
));
// The OverscrollIndicator should respect the [OverscrollIndicatorNotification.paintOffset] setting.
expect
(
painter
,
paints
..
scale
(
y:
-
1.0
)..
save
()..
translate
(
y:
50.0
)..
scale
()..
circle
());
// Reverse scroll direction.
await
tester
.
dragFrom
(
const
Offset
(
200.0
,
200.0
),
const
Offset
(
0.0
,
30.0
));
await
tester
.
pump
();
// The
painter should follow the scroll direction
.
// The
OverscrollIndicator should move with the CustomScrollView
.
expect
(
painter
,
paints
..
scale
(
y:
-
1.0
)..
save
()..
translate
(
y:
50.0
-
30.0
)..
scale
()..
circle
());
});
});
...
...
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