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
58c4bd10
Unverified
Commit
58c4bd10
authored
Apr 08, 2021
by
Kate Lovett
Committed by
GitHub
Apr 08, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "improve the scrollbar behavior when viewport size changed (#76102)" (#80059)
parent
913c5702
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
88 additions
and
133 deletions
+88
-133
scrollbar.dart
packages/flutter/lib/src/widgets/scrollbar.dart
+88
-102
scrollbar_test.dart
packages/flutter/test/widgets/scrollbar_test.dart
+0
-31
No files found.
packages/flutter/lib/src/widgets/scrollbar.dart
View file @
58c4bd10
...
...
@@ -276,21 +276,14 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
Rect
?
_trackRect
;
late
double
_thumbOffset
;
/// Update with new [ScrollMetrics].
If the metrics change, the scrollbar will
///
show and redraw itself
based on these new metrics.
/// Update with new [ScrollMetrics].
The scrollbar will show and redraw itself
/// based on these new metrics.
///
/// The scrollbar will remain on screen.
void
update
(
ScrollMetrics
metrics
,
AxisDirection
axisDirection
,
)
{
if
(
_lastMetrics
!=
null
&&
_lastMetrics
!.
extentBefore
==
metrics
.
extentBefore
&&
_lastMetrics
!.
extentInside
==
metrics
.
extentInside
&&
_lastMetrics
!.
extentAfter
==
metrics
.
extentAfter
&&
_lastAxisDirection
==
axisDirection
)
return
;
_lastMetrics
=
metrics
;
_lastAxisDirection
=
axisDirection
;
notifyListeners
();
...
...
@@ -937,90 +930,90 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv
@override
void
didChangeDependencies
()
{
super
.
didChangeDependencies
();
_maybe
RequestEmptyScrollEvent
();
_maybe
TriggerScrollbar
();
}
// Waits one frame and cause an empty scroll event (zero delta pixels).
//
// This allows the thumb to show immediately when isAlwaysShown is true.
// A scroll event is required in order to paint the thumb.
void
_maybeRequestEmptyScrollEvent
()
{
if
(!
showScrollbar
)
return
;
void
_maybeTriggerScrollbar
()
{
WidgetsBinding
.
instance
!.
addPostFrameCallback
((
Duration
duration
)
{
_fadeoutTimer
?.
cancel
();
// Wait one frame and cause an empty scroll event. This allows the
// thumb to show immediately when isAlwaysShown is true. A scroll
// event is required in order to paint the thumb.
final
ScrollController
?
scrollController
=
widget
.
controller
??
PrimaryScrollController
.
of
(
context
);
final
bool
tryPrimary
=
widget
.
controller
==
null
;
final
String
controllerForError
=
tryPrimary
?
'provided ScrollController'
:
'PrimaryScrollController'
;
assert
(
scrollController
!=
null
,
'A ScrollController is required when Scrollbar.isAlwaysShown is true. '
'
${tryPrimary ? 'The Scrollbar was not provided a ScrollController, '
'and attempted to use the PrimaryScrollController, but none was found.' :''}
'
,
);
assert
(()
{
if
(!
scrollController
!.
hasClients
)
{
throw
FlutterError
.
fromParts
(<
DiagnosticsNode
>[
ErrorSummary
(
'The Scrollbar
\'
s ScrollController has no ScrollPosition attached.'
,
),
ErrorDescription
(
'A Scrollbar cannot be painted without a ScrollPosition. '
,
),
ErrorHint
(
'The Scrollbar attempted to use the
$controllerForError
. This '
'ScrollController should be associated with the ScrollView that '
'the Scrollbar is being applied to. '
'
${tryPrimary
? 'A ScrollView with an Axis.vertical '
'ScrollDirection will automatically use the '
'PrimaryScrollController if the user has not provided a '
'ScrollController, but a ScrollDirection of Axis.horizontal will '
'not. To use the PrimaryScrollController explicitly, set ScrollView.primary '
'to true for the Scrollable widget.'
: 'When providing your own ScrollController, ensure both the '
'Scrollbar and the Scrollable widget use the same one.'
}
'
,
),
]);
}
return
true
;
}());
assert
(()
{
try
{
scrollController
!.
position
;
}
catch
(
_
)
{
throw
FlutterError
.
fromParts
(<
DiagnosticsNode
>[
ErrorSummary
(
'The
$controllerForError
is currently attached to more than one '
'ScrollPosition.'
,
),
ErrorDescription
(
'The Scrollbar requires a single ScrollPosition in order to be painted.'
,
),
ErrorHint
(
'When Scrollbar.isAlwaysShown is true, the associated Scrollable '
'widgets must have unique ScrollControllers. '
'
${tryPrimary
? 'The PrimaryScrollController is used by default for '
'ScrollViews with an Axis.vertical ScrollDirection, '
'unless the ScrollView has been provided its own '
'ScrollController. More than one Scrollable may have tried '
'to use the PrimaryScrollController of the current context.'
: 'The provided ScrollController must be unique to a '
'Scrollable widget.'
}
'
,
),
]);
}
return
true
;
}());
scrollController
!.
position
.
didUpdateScrollPositionBy
(
0
);
if
(
showScrollbar
)
{
_fadeoutTimer
?.
cancel
();
// Wait one frame and cause an empty scroll event. This allows the
// thumb to show immediately when isAlwaysShown is true. A scroll
// event is required in order to paint the thumb.
final
ScrollController
?
scrollController
=
widget
.
controller
??
PrimaryScrollController
.
of
(
context
);
final
bool
tryPrimary
=
widget
.
controller
==
null
;
final
String
controllerForError
=
tryPrimary
?
'provided ScrollController'
:
'PrimaryScrollController'
;
assert
(
scrollController
!=
null
,
'A ScrollController is required when Scrollbar.isAlwaysShown is true. '
'
${tryPrimary ? 'The Scrollbar was not provided a ScrollController, '
'and attempted to use the PrimaryScrollController, but none was found.' :''}
'
,
);
assert
(()
{
if
(!
scrollController
!.
hasClients
)
{
throw
FlutterError
.
fromParts
(<
DiagnosticsNode
>[
ErrorSummary
(
'The Scrollbar
\'
s ScrollController has no ScrollPosition attached.'
,
),
ErrorDescription
(
'A Scrollbar cannot be painted without a ScrollPosition. '
,
),
ErrorHint
(
'The Scrollbar attempted to use the
$controllerForError
. This '
'ScrollController should be associated with the ScrollView that '
'the Scrollbar is being applied to. '
'
${tryPrimary
? 'A ScrollView with an Axis.vertical '
'ScrollDirection will automatically use the '
'PrimaryScrollController if the user has not provided a '
'ScrollController, but a ScrollDirection of Axis.horizontal will '
'not. To use the PrimaryScrollController explicitly, set ScrollView.primary '
'to true for the Scrollable widget.'
: 'When providing your own ScrollController, ensure both the '
'Scrollbar and the Scrollable widget use the same one.'
}
'
,
),
]);
}
return
true
;
}());
assert
(()
{
try
{
scrollController
!.
position
;
}
catch
(
_
)
{
throw
FlutterError
.
fromParts
(<
DiagnosticsNode
>[
ErrorSummary
(
'The
$controllerForError
is currently attached to more than one '
'ScrollPosition.'
,
),
ErrorDescription
(
'The Scrollbar requires a single ScrollPosition in order to be painted.'
,
),
ErrorHint
(
'When Scrollbar.isAlwaysShown is true, the associated Scrollable '
'widgets must have unique ScrollControllers. '
'
${tryPrimary
? 'The PrimaryScrollController is used by default for '
'ScrollViews with an Axis.vertical ScrollDirection, '
'unless the ScrollView has been provided its own '
'ScrollController. More than one Scrollable may have tried '
'to use the PrimaryScrollController of the current context.'
: 'The provided ScrollController must be unique to a '
'Scrollable widget.'
}
'
,
),
]);
}
return
true
;
}());
scrollController
!.
position
.
didUpdateScrollPositionBy
(
0
);
}
});
}
...
...
@@ -1042,14 +1035,13 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv
@override
void
didUpdateWidget
(
T
oldWidget
)
{
super
.
didUpdateWidget
(
oldWidget
);
// If `isAlwaysShown` is true and does not change,
// it may be necessary to trigger a scroll event to show or hide the bar when the
// scrollable widget viewport size changed.
if
(
widget
.
isAlwaysShown
==
true
)
{
_maybeRequestEmptyScrollEvent
();
_fadeoutAnimationController
.
animateTo
(
1.0
);
}
else
if
(
widget
.
isAlwaysShown
!=
oldWidget
.
isAlwaysShown
)
{
_fadeoutAnimationController
.
reverse
();
if
(
widget
.
isAlwaysShown
!=
oldWidget
.
isAlwaysShown
)
{
if
(
widget
.
isAlwaysShown
==
true
)
{
_maybeTriggerScrollbar
();
_fadeoutAnimationController
.
animateTo
(
1.0
);
}
else
{
_fadeoutAnimationController
.
reverse
();
}
}
}
...
...
@@ -1211,19 +1203,13 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv
return
false
;
final
ScrollMetrics
metrics
=
notification
.
metrics
;
if
(
metrics
.
maxScrollExtent
<=
metrics
.
minScrollExtent
)
{
// Hide the bar when the Scrollable widget has no space to scroll.
if
(
_fadeoutAnimationController
.
status
!=
AnimationStatus
.
dismissed
&&
_fadeoutAnimationController
.
status
!=
AnimationStatus
.
reverse
)
_fadeoutAnimationController
.
reverse
();
if
(
metrics
.
maxScrollExtent
<=
metrics
.
minScrollExtent
)
return
false
;
}
if
(
notification
is
ScrollUpdateNotification
||
notification
is
OverscrollNotification
)
{
// Any movements always makes the scrollbar start showing up.
if
(
_fadeoutAnimationController
.
status
!=
AnimationStatus
.
forward
&&
_fadeoutAnimationController
.
status
!=
AnimationStatus
.
completed
)
if
(
_fadeoutAnimationController
.
status
!=
AnimationStatus
.
forward
)
_fadeoutAnimationController
.
forward
();
_fadeoutTimer
?.
cancel
();
...
...
packages/flutter/test/widgets/scrollbar_test.dart
View file @
58c4bd10
...
...
@@ -1152,35 +1152,4 @@ void main() {
),
);
});
testWidgets
(
'The bar can show or hide when the viewport size change'
,
(
WidgetTester
tester
)
async
{
final
ScrollController
scrollController
=
ScrollController
();
Widget
buildFrame
(
double
height
)
{
return
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
MediaQuery
(
data:
const
MediaQueryData
(),
child:
RawScrollbar
(
controller:
scrollController
,
isAlwaysShown:
true
,
child:
SingleChildScrollView
(
controller:
scrollController
,
child:
SizedBox
(
width:
double
.
infinity
,
height:
height
)
),
),
),
);
}
await
tester
.
pumpWidget
(
buildFrame
(
600.0
));
await
tester
.
pumpAndSettle
();
expect
(
find
.
byType
(
RawScrollbar
),
isNot
(
paints
..
rect
()));
// Not shown.
await
tester
.
pumpWidget
(
buildFrame
(
600.1
));
await
tester
.
pumpAndSettle
();
expect
(
find
.
byType
(
RawScrollbar
),
paints
..
rect
()..
rect
());
// Show the bar.
await
tester
.
pumpWidget
(
buildFrame
(
600.0
));
await
tester
.
pumpAndSettle
();
expect
(
find
.
byType
(
RawScrollbar
),
isNot
(
paints
..
rect
()));
// Hide the bar.
});
}
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