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
e40610d6
Unverified
Commit
e40610d6
authored
Apr 02, 2021
by
Kate Lovett
Committed by
GitHub
Apr 02, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Automatically applying Scrollbars on desktop platforms with configurable ScrollBehaviors (#78588)
parent
b083bc14
Changes
27
Show whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
725 additions
and
321 deletions
+725
-321
app.dart
packages/flutter/lib/src/cupertino/app.dart
+31
-3
app.dart
packages/flutter/lib/src/material/app.dart
+36
-5
dropdown.dart
packages/flutter/lib/src/material/dropdown.dart
+8
-16
editable_text.dart
packages/flutter/lib/src/widgets/editable_text.dart
+26
-0
list_wheel_scroll_view.dart
packages/flutter/lib/src/widgets/list_wheel_scroll_view.dart
+21
-0
nested_scroll_view.dart
packages/flutter/lib/src/widgets/nested_scroll_view.dart
+28
-3
overscroll_indicator.dart
packages/flutter/lib/src/widgets/overscroll_indicator.dart
+2
-2
page_view.dart
packages/flutter/lib/src/widgets/page_view.dart
+22
-2
scroll_configuration.dart
packages/flutter/lib/src/widgets/scroll_configuration.dart
+149
-7
scroll_context.dart
packages/flutter/lib/src/widgets/scroll_context.dart
+1
-1
scroll_view.dart
packages/flutter/lib/src/widgets/scroll_view.dart
+17
-0
scrollable.dart
packages/flutter/lib/src/widgets/scrollable.dart
+96
-14
scrollbar.dart
packages/flutter/lib/src/widgets/scrollbar.dart
+18
-3
app_test.dart
packages/flutter/test/cupertino/app_test.dart
+3
-1
nav_bar_test.dart
packages/flutter/test/cupertino/nav_bar_test.dart
+0
-1
refresh_test.dart
packages/flutter/test/cupertino/refresh_test.dart
+64
-88
app_test.dart
packages/flutter/test/material/app_test.dart
+3
-1
scrollbar_test.dart
packages/flutter/test/material/scrollbar_test.dart
+55
-68
scrollbar_theme_test.dart
packages/flutter/test/material/scrollbar_theme_test.dart
+59
-42
viewport_test.dart
packages/flutter/test/rendering/viewport_test.dart
+21
-18
app_test.dart
packages/flutter/test/widgets/app_test.dart
+0
-5
draggable_scrollable_sheet_test.dart
...flutter/test/widgets/draggable_scrollable_sheet_test.dart
+29
-26
overscroll_indicator_test.dart
packages/flutter/test/widgets/overscroll_indicator_test.dart
+14
-10
range_maintaining_scroll_physics_test.dart
...r/test/widgets/range_maintaining_scroll_physics_test.dart
+6
-1
scrollable_test.dart
packages/flutter/test/widgets/scrollable_test.dart
+8
-0
slivers_evil_test.dart
packages/flutter/test/widgets/slivers_evil_test.dart
+5
-3
state_setting_in_scrollables_test.dart
...utter/test/widgets/state_setting_in_scrollables_test.dart
+3
-1
No files found.
packages/flutter/lib/src/cupertino/app.dart
View file @
e40610d6
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
import
'package:flutter/foundation.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:flutter/widgets.dart'
;
import
'button.dart'
;
import
'button.dart'
;
...
@@ -10,6 +11,7 @@ import 'icons.dart';
...
@@ -10,6 +11,7 @@ import 'icons.dart';
import
'interface_level.dart'
;
import
'interface_level.dart'
;
import
'localizations.dart'
;
import
'localizations.dart'
;
import
'route.dart'
;
import
'route.dart'
;
import
'scrollbar.dart'
;
import
'theme.dart'
;
import
'theme.dart'
;
/// An application that uses Cupertino design.
/// An application that uses Cupertino design.
...
@@ -422,14 +424,40 @@ class CupertinoApp extends StatefulWidget {
...
@@ -422,14 +424,40 @@ class CupertinoApp extends StatefulWidget {
/// Setting a [CupertinoScrollBehavior] will result in descendant [Scrollable] widgets
/// Setting a [CupertinoScrollBehavior] will result in descendant [Scrollable] widgets
/// using [BouncingScrollPhysics] by default. No [GlowingOverscrollIndicator] is
/// using [BouncingScrollPhysics] by default. No [GlowingOverscrollIndicator] is
/// applied when using a [CupertinoScrollBehavior] either, regardless of platform.
/// applied when using a [CupertinoScrollBehavior] either, regardless of platform.
/// When executing on desktop platforms, a [CupertinoScrollbar] is applied to the child.
///
///
/// See also:
/// See also:
///
///
/// * [ScrollBehavior], the default scrolling behavior extended by this class.
/// * [ScrollBehavior], the default scrolling behavior extended by this class.
class
CupertinoScrollBehavior
extends
ScrollBehavior
{
class
CupertinoScrollBehavior
extends
ScrollBehavior
{
/// Creates a CupertinoScrollBehavior that uses [BouncingScrollPhysics] and
/// adds [CupertinoScrollbar]s on desktop platforms.
const
CupertinoScrollBehavior
();
@override
Widget
buildScrollbar
(
BuildContext
context
,
Widget
child
,
ScrollableDetails
details
)
{
// When modifying this function, consider modifying the implementation in
// the base class as well.
switch
(
getPlatform
(
context
))
{
case
TargetPlatform
.
linux
:
case
TargetPlatform
.
macOS
:
case
TargetPlatform
.
windows
:
return
CupertinoScrollbar
(
child:
child
,
controller:
details
.
controller
,
);
case
TargetPlatform
.
android
:
case
TargetPlatform
.
fuchsia
:
case
TargetPlatform
.
iOS
:
return
child
;
}
}
@override
@override
Widget
buildViewportChrome
(
BuildContext
context
,
Widget
child
,
AxisDirection
axisDirection
)
{
Widget
buildOverscrollIndicator
(
BuildContext
context
,
Widget
child
,
ScrollableDetails
details
)
{
// Never build any overscroll glow indicators.
// No overscroll indicator.
// When modifying this function, consider modifying the implementation in
// the base class as well.
return
child
;
return
child
;
}
}
...
@@ -544,7 +572,7 @@ class _CupertinoAppState extends State<CupertinoApp> {
...
@@ -544,7 +572,7 @@ class _CupertinoAppState extends State<CupertinoApp> {
final
CupertinoThemeData
effectiveThemeData
=
widget
.
theme
??
const
CupertinoThemeData
();
final
CupertinoThemeData
effectiveThemeData
=
widget
.
theme
??
const
CupertinoThemeData
();
return
ScrollConfiguration
(
return
ScrollConfiguration
(
behavior:
widget
.
scrollBehavior
??
CupertinoScrollBehavior
(),
behavior:
widget
.
scrollBehavior
??
const
CupertinoScrollBehavior
(),
child:
CupertinoUserInterfaceLevel
(
child:
CupertinoUserInterfaceLevel
(
data:
CupertinoUserInterfaceLevelData
.
base
,
data:
CupertinoUserInterfaceLevelData
.
base
,
child:
CupertinoTheme
(
child:
CupertinoTheme
(
...
...
packages/flutter/lib/src/material/app.dart
View file @
e40610d6
...
@@ -14,6 +14,7 @@ import 'icons.dart';
...
@@ -14,6 +14,7 @@ import 'icons.dart';
import
'material_localizations.dart'
;
import
'material_localizations.dart'
;
import
'page.dart'
;
import
'page.dart'
;
import
'scaffold.dart'
show
ScaffoldMessenger
,
ScaffoldMessengerState
;
import
'scaffold.dart'
show
ScaffoldMessenger
,
ScaffoldMessengerState
;
import
'scrollbar.dart'
;
import
'theme.dart'
;
import
'theme.dart'
;
/// [MaterialApp] uses this [TextStyle] as its [DefaultTextStyle] to encourage
/// [MaterialApp] uses this [TextStyle] as its [DefaultTextStyle] to encourage
...
@@ -684,17 +685,47 @@ class MaterialApp extends StatefulWidget {
...
@@ -684,17 +685,47 @@ class MaterialApp extends StatefulWidget {
/// [GlowingOverscrollIndicator] to [Scrollable] descendants when executing on
/// [GlowingOverscrollIndicator] to [Scrollable] descendants when executing on
/// [TargetPlatform.android] and [TargetPlatform.fuchsia].
/// [TargetPlatform.android] and [TargetPlatform.fuchsia].
///
///
/// When using the desktop platform, if the [Scrollable] widget scrolls in the
/// [Axis.vertical], a [Scrollbar] is applied.
///
/// See also:
/// See also:
///
///
/// * [ScrollBehavior], the default scrolling behavior extended by this class.
/// * [ScrollBehavior], the default scrolling behavior extended by this class.
class
MaterialScrollBehavior
extends
ScrollBehavior
{
class
MaterialScrollBehavior
extends
ScrollBehavior
{
/// Creates a MaterialScrollBehavior that decorates [Scrollable]s with
/// [GlowingOverscrollIndicator]s and [Scrollbar]s based on the current
/// platform and provided [ScrollableDetails].
const
MaterialScrollBehavior
();
@override
@override
TargetPlatform
getPlatform
(
BuildContext
context
)
{
TargetPlatform
getPlatform
(
BuildContext
context
)
=>
Theme
.
of
(
context
).
platform
;
return
Theme
.
of
(
context
).
platform
;
@override
Widget
buildScrollbar
(
BuildContext
context
,
Widget
child
,
ScrollableDetails
details
)
{
// When modifying this function, consider modifying the implementation in
// the base class as well.
switch
(
axisDirectionToAxis
(
details
.
direction
))
{
case
Axis
.
horizontal
:
return
child
;
case
Axis
.
vertical
:
switch
(
getPlatform
(
context
))
{
case
TargetPlatform
.
linux
:
case
TargetPlatform
.
macOS
:
case
TargetPlatform
.
windows
:
return
Scrollbar
(
child:
child
,
controller:
details
.
controller
,
);
case
TargetPlatform
.
android
:
case
TargetPlatform
.
fuchsia
:
case
TargetPlatform
.
iOS
:
return
child
;
}
}
}
}
@override
@override
Widget
build
ViewportChrome
(
BuildContext
context
,
Widget
child
,
AxisDirection
axisDirection
)
{
Widget
build
OverscrollIndicator
(
BuildContext
context
,
Widget
child
,
ScrollableDetails
details
)
{
// When modifying this function, consider modifying the implementation in
// When modifying this function, consider modifying the implementation in
// the base class as well.
// the base class as well.
switch
(
getPlatform
(
context
))
{
switch
(
getPlatform
(
context
))
{
...
@@ -707,7 +738,7 @@ class MaterialScrollBehavior extends ScrollBehavior {
...
@@ -707,7 +738,7 @@ class MaterialScrollBehavior extends ScrollBehavior {
case
TargetPlatform
.
fuchsia
:
case
TargetPlatform
.
fuchsia
:
return
GlowingOverscrollIndicator
(
return
GlowingOverscrollIndicator
(
child:
child
,
child:
child
,
axisDirection:
axisD
irection
,
axisDirection:
details
.
d
irection
,
color:
Theme
.
of
(
context
).
colorScheme
.
secondary
,
color:
Theme
.
of
(
context
).
colorScheme
.
secondary
,
);
);
}
}
...
@@ -880,7 +911,7 @@ class _MaterialAppState extends State<MaterialApp> {
...
@@ -880,7 +911,7 @@ class _MaterialAppState extends State<MaterialApp> {
}());
}());
return
ScrollConfiguration
(
return
ScrollConfiguration
(
behavior:
widget
.
scrollBehavior
??
MaterialScrollBehavior
(),
behavior:
widget
.
scrollBehavior
??
const
MaterialScrollBehavior
(),
child:
HeroControllerScope
(
child:
HeroControllerScope
(
controller:
_heroController
,
controller:
_heroController
,
child:
result
,
child:
result
,
...
...
packages/flutter/lib/src/material/dropdown.dart
View file @
e40610d6
...
@@ -88,21 +88,6 @@ class _DropdownMenuPainter extends CustomPainter {
...
@@ -88,21 +88,6 @@ class _DropdownMenuPainter extends CustomPainter {
}
}
}
}
// Do not use the platform-specific default scroll configuration.
// Dropdown menus should never overscroll or display an overscroll indicator.
class
_DropdownScrollBehavior
extends
ScrollBehavior
{
const
_DropdownScrollBehavior
();
@override
TargetPlatform
getPlatform
(
BuildContext
context
)
=>
Theme
.
of
(
context
).
platform
;
@override
Widget
buildViewportChrome
(
BuildContext
context
,
Widget
child
,
AxisDirection
axisDirection
)
=>
child
;
@override
ScrollPhysics
getScrollPhysics
(
BuildContext
context
)
=>
const
ClampingScrollPhysics
();
}
// The widget that is the button wrapping the menu items.
// The widget that is the button wrapping the menu items.
class
_DropdownMenuItemButton
<
T
>
extends
StatefulWidget
{
class
_DropdownMenuItemButton
<
T
>
extends
StatefulWidget
{
const
_DropdownMenuItemButton
({
const
_DropdownMenuItemButton
({
...
@@ -289,7 +274,14 @@ class _DropdownMenuState<T> extends State<_DropdownMenu<T>> {
...
@@ -289,7 +274,14 @@ class _DropdownMenuState<T> extends State<_DropdownMenu<T>> {
type:
MaterialType
.
transparency
,
type:
MaterialType
.
transparency
,
textStyle:
route
.
style
,
textStyle:
route
.
style
,
child:
ScrollConfiguration
(
child:
ScrollConfiguration
(
behavior:
const
_DropdownScrollBehavior
(),
// Dropdown menus should never overscroll or display an overscroll indicator.
// The default scrollbar platforms will apply.
// Platform must use Theme and ScrollPhysics must be Clamping.
behavior:
ScrollConfiguration
.
of
(
context
).
copyWith
(
overscroll:
false
,
physics:
const
ClampingScrollPhysics
(),
platform:
Theme
.
of
(
context
).
platform
,
),
child:
PrimaryScrollController
(
child:
PrimaryScrollController
(
controller:
widget
.
route
.
scrollController
!,
controller:
widget
.
route
.
scrollController
!,
child:
Scrollbar
(
child:
Scrollbar
(
...
...
packages/flutter/lib/src/widgets/editable_text.dart
View file @
e40610d6
...
@@ -23,6 +23,7 @@ import 'focus_scope.dart';
...
@@ -23,6 +23,7 @@ import 'focus_scope.dart';
import
'framework.dart'
;
import
'framework.dart'
;
import
'localizations.dart'
;
import
'localizations.dart'
;
import
'media_query.dart'
;
import
'media_query.dart'
;
import
'scroll_configuration.dart'
;
import
'scroll_controller.dart'
;
import
'scroll_controller.dart'
;
import
'scroll_physics.dart'
;
import
'scroll_physics.dart'
;
import
'scrollable.dart'
;
import
'scrollable.dart'
;
...
@@ -493,6 +494,7 @@ class EditableText extends StatefulWidget {
...
@@ -493,6 +494,7 @@ class EditableText extends StatefulWidget {
this
.
autofillHints
,
this
.
autofillHints
,
this
.
clipBehavior
=
Clip
.
hardEdge
,
this
.
clipBehavior
=
Clip
.
hardEdge
,
this
.
restorationId
,
this
.
restorationId
,
this
.
scrollBehavior
,
})
:
assert
(
controller
!=
null
),
})
:
assert
(
controller
!=
null
),
assert
(
focusNode
!=
null
),
assert
(
focusNode
!=
null
),
assert
(
obscuringCharacter
!=
null
&&
obscuringCharacter
.
length
==
1
),
assert
(
obscuringCharacter
!=
null
&&
obscuringCharacter
.
length
==
1
),
...
@@ -1201,6 +1203,10 @@ class EditableText extends StatefulWidget {
...
@@ -1201,6 +1203,10 @@ class EditableText extends StatefulWidget {
///
///
/// See [Scrollable.physics].
/// See [Scrollable.physics].
/// {@endtemplate}
/// {@endtemplate}
///
/// If an explicit [ScrollBehavior] is provided to [scrollBehavior], the
/// [ScrollPhysics] provided by that behavior will take precedence after
/// [scrollPhysics].
final
ScrollPhysics
?
scrollPhysics
;
final
ScrollPhysics
?
scrollPhysics
;
/// {@template flutter.widgets.editableText.selectionEnabled}
/// {@template flutter.widgets.editableText.selectionEnabled}
...
@@ -1305,6 +1311,23 @@ class EditableText extends StatefulWidget {
...
@@ -1305,6 +1311,23 @@ class EditableText extends StatefulWidget {
/// Flutter.
/// Flutter.
final
String
?
restorationId
;
final
String
?
restorationId
;
/// {@template flutter.widgets.shadow.scrollBehavior}
/// A [ScrollBehavior] that will be applied to this widget individually.
///
/// Defaults to null, wherein the inherited [ScrollBehavior] is copied and
/// modified to alter the viewport decoration, like [Scrollbar]s.
/// {@endtemplate}
///
/// [ScrollBehavior]s also provide [ScrollPhysics]. If an explicit
/// [ScrollPhysics] is provided in [scrollPhysics], it will take precedence,
/// followed by [scrollBehavior], and then the inherited ancestor
/// [ScrollBehavior].
///
/// The [ScrollBehavior] of the inherited [ScrollConfiguration] will be
/// modified by default to only apply a [Scrollbar] if [maxLines] is greater
/// than 1.
final
ScrollBehavior
?
scrollBehavior
;
// Infer the keyboard type of an `EditableText` if it's not specified.
// Infer the keyboard type of an `EditableText` if it's not specified.
static
TextInputType
_inferKeyboardType
({
static
TextInputType
_inferKeyboardType
({
required
Iterable
<
String
>?
autofillHints
,
required
Iterable
<
String
>?
autofillHints
,
...
@@ -2609,6 +2632,9 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
...
@@ -2609,6 +2632,9 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
physics:
widget
.
scrollPhysics
,
physics:
widget
.
scrollPhysics
,
dragStartBehavior:
widget
.
dragStartBehavior
,
dragStartBehavior:
widget
.
dragStartBehavior
,
restorationId:
widget
.
restorationId
,
restorationId:
widget
.
restorationId
,
scrollBehavior:
widget
.
scrollBehavior
??
// Remove scrollbars if only single line
(
_isMultiline
?
null
:
ScrollConfiguration
.
of
(
context
).
copyWith
(
scrollbars:
false
)),
viewportBuilder:
(
BuildContext
context
,
ViewportOffset
offset
)
{
viewportBuilder:
(
BuildContext
context
,
ViewportOffset
offset
)
{
return
CompositedTransformTarget
(
return
CompositedTransformTarget
(
link:
_toolbarLayerLink
,
link:
_toolbarLayerLink
,
...
...
packages/flutter/lib/src/widgets/list_wheel_scroll_view.dart
View file @
e40610d6
...
@@ -12,6 +12,7 @@ import 'package:flutter/scheduler.dart';
...
@@ -12,6 +12,7 @@ import 'package:flutter/scheduler.dart';
import
'basic.dart'
;
import
'basic.dart'
;
import
'framework.dart'
;
import
'framework.dart'
;
import
'notification_listener.dart'
;
import
'notification_listener.dart'
;
import
'scroll_configuration.dart'
;
import
'scroll_context.dart'
;
import
'scroll_context.dart'
;
import
'scroll_controller.dart'
;
import
'scroll_controller.dart'
;
import
'scroll_metrics.dart'
;
import
'scroll_metrics.dart'
;
...
@@ -431,6 +432,7 @@ class _FixedExtentScrollable extends Scrollable {
...
@@ -431,6 +432,7 @@ class _FixedExtentScrollable extends Scrollable {
required
this
.
itemExtent
,
required
this
.
itemExtent
,
required
ViewportBuilder
viewportBuilder
,
required
ViewportBuilder
viewportBuilder
,
String
?
restorationId
,
String
?
restorationId
,
ScrollBehavior
?
scrollBehavior
,
})
:
super
(
})
:
super
(
key:
key
,
key:
key
,
axisDirection:
axisDirection
,
axisDirection:
axisDirection
,
...
@@ -438,6 +440,7 @@ class _FixedExtentScrollable extends Scrollable {
...
@@ -438,6 +440,7 @@ class _FixedExtentScrollable extends Scrollable {
physics:
physics
,
physics:
physics
,
viewportBuilder:
viewportBuilder
,
viewportBuilder:
viewportBuilder
,
restorationId:
restorationId
,
restorationId:
restorationId
,
scrollBehavior:
scrollBehavior
,
);
);
final
double
itemExtent
;
final
double
itemExtent
;
...
@@ -584,6 +587,7 @@ class ListWheelScrollView extends StatefulWidget {
...
@@ -584,6 +587,7 @@ class ListWheelScrollView extends StatefulWidget {
this
.
renderChildrenOutsideViewport
=
false
,
this
.
renderChildrenOutsideViewport
=
false
,
this
.
clipBehavior
=
Clip
.
hardEdge
,
this
.
clipBehavior
=
Clip
.
hardEdge
,
this
.
restorationId
,
this
.
restorationId
,
this
.
scrollBehavior
,
required
List
<
Widget
>
children
,
required
List
<
Widget
>
children
,
})
:
assert
(
children
!=
null
),
})
:
assert
(
children
!=
null
),
assert
(
diameterRatio
!=
null
),
assert
(
diameterRatio
!=
null
),
...
@@ -625,6 +629,7 @@ class ListWheelScrollView extends StatefulWidget {
...
@@ -625,6 +629,7 @@ class ListWheelScrollView extends StatefulWidget {
this
.
renderChildrenOutsideViewport
=
false
,
this
.
renderChildrenOutsideViewport
=
false
,
this
.
clipBehavior
=
Clip
.
hardEdge
,
this
.
clipBehavior
=
Clip
.
hardEdge
,
this
.
restorationId
,
this
.
restorationId
,
this
.
scrollBehavior
,
required
this
.
childDelegate
,
required
this
.
childDelegate
,
})
:
assert
(
childDelegate
!=
null
),
})
:
assert
(
childDelegate
!=
null
),
assert
(
diameterRatio
!=
null
),
assert
(
diameterRatio
!=
null
),
...
@@ -669,6 +674,10 @@ class ListWheelScrollView extends StatefulWidget {
...
@@ -669,6 +674,10 @@ class ListWheelScrollView extends StatefulWidget {
/// For example, determines how the scroll view continues to animate after the
/// For example, determines how the scroll view continues to animate after the
/// user stops dragging the scroll view.
/// user stops dragging the scroll view.
///
///
/// If an explicit [ScrollBehavior] is provided to [scrollBehavior], the
/// [ScrollPhysics] provided by that behavior will take precedence after
/// [physics].
///
/// Defaults to matching platform conventions.
/// Defaults to matching platform conventions.
final
ScrollPhysics
?
physics
;
final
ScrollPhysics
?
physics
;
...
@@ -716,6 +725,17 @@ class ListWheelScrollView extends StatefulWidget {
...
@@ -716,6 +725,17 @@ class ListWheelScrollView extends StatefulWidget {
/// {@macro flutter.widgets.scrollable.restorationId}
/// {@macro flutter.widgets.scrollable.restorationId}
final
String
?
restorationId
;
final
String
?
restorationId
;
/// {@macro flutter.widgets.shadow.scrollBehavior}
///
/// [ScrollBehavior]s also provide [ScrollPhysics]. If an explicit
/// [ScrollPhysics] is provided in [physics], it will take precedence,
/// followed by [scrollBehavior], and then the inherited ancestor
/// [ScrollBehavior].
///
/// The [ScrollBehavior] of the inherited [ScrollConfiguration] will be
/// modified by default to not apply a [Scrollbar].
final
ScrollBehavior
?
scrollBehavior
;
@override
@override
_ListWheelScrollViewState
createState
()
=>
_ListWheelScrollViewState
();
_ListWheelScrollViewState
createState
()
=>
_ListWheelScrollViewState
();
}
}
...
@@ -769,6 +789,7 @@ class _ListWheelScrollViewState extends State<ListWheelScrollView> {
...
@@ -769,6 +789,7 @@ class _ListWheelScrollViewState extends State<ListWheelScrollView> {
physics:
widget
.
physics
,
physics:
widget
.
physics
,
itemExtent:
widget
.
itemExtent
,
itemExtent:
widget
.
itemExtent
,
restorationId:
widget
.
restorationId
,
restorationId:
widget
.
restorationId
,
scrollBehavior:
widget
.
scrollBehavior
??
ScrollConfiguration
.
of
(
context
).
copyWith
(
scrollbars:
false
),
viewportBuilder:
(
BuildContext
context
,
ViewportOffset
offset
)
{
viewportBuilder:
(
BuildContext
context
,
ViewportOffset
offset
)
{
return
ListWheelViewport
(
return
ListWheelViewport
(
diameterRatio:
widget
.
diameterRatio
,
diameterRatio:
widget
.
diameterRatio
,
...
...
packages/flutter/lib/src/widgets/nested_scroll_view.dart
View file @
e40610d6
...
@@ -13,6 +13,7 @@ import 'basic.dart';
...
@@ -13,6 +13,7 @@ import 'basic.dart';
import
'framework.dart'
;
import
'framework.dart'
;
import
'primary_scroll_controller.dart'
;
import
'primary_scroll_controller.dart'
;
import
'scroll_activity.dart'
;
import
'scroll_activity.dart'
;
import
'scroll_configuration.dart'
;
import
'scroll_context.dart'
;
import
'scroll_context.dart'
;
import
'scroll_controller.dart'
;
import
'scroll_controller.dart'
;
import
'scroll_metrics.dart'
;
import
'scroll_metrics.dart'
;
...
@@ -369,6 +370,7 @@ class NestedScrollView extends StatefulWidget {
...
@@ -369,6 +370,7 @@ class NestedScrollView extends StatefulWidget {
this
.
floatHeaderSlivers
=
false
,
this
.
floatHeaderSlivers
=
false
,
this
.
clipBehavior
=
Clip
.
hardEdge
,
this
.
clipBehavior
=
Clip
.
hardEdge
,
this
.
restorationId
,
this
.
restorationId
,
this
.
scrollBehavior
,
})
:
assert
(
scrollDirection
!=
null
),
})
:
assert
(
scrollDirection
!=
null
),
assert
(
reverse
!=
null
),
assert
(
reverse
!=
null
),
assert
(
headerSliverBuilder
!=
null
),
assert
(
headerSliverBuilder
!=
null
),
...
@@ -407,6 +409,10 @@ class NestedScrollView extends StatefulWidget {
...
@@ -407,6 +409,10 @@ class NestedScrollView extends StatefulWidget {
/// [ScrollPhysics.createBallisticSimulation] allows this particular aspect of
/// [ScrollPhysics.createBallisticSimulation] allows this particular aspect of
/// the physics to be overridden).
/// the physics to be overridden).
///
///
/// If an explicit [ScrollBehavior] is provided to [scrollBehavior], the
/// [ScrollPhysics] provided by that behavior will take precedence after
/// [physics].
///
/// Defaults to matching platform conventions.
/// Defaults to matching platform conventions.
///
///
/// The [ScrollPhysics.applyBoundaryConditions] implementation of the provided
/// The [ScrollPhysics.applyBoundaryConditions] implementation of the provided
...
@@ -453,6 +459,20 @@ class NestedScrollView extends StatefulWidget {
...
@@ -453,6 +459,20 @@ class NestedScrollView extends StatefulWidget {
/// {@macro flutter.widgets.scrollable.restorationId}
/// {@macro flutter.widgets.scrollable.restorationId}
final
String
?
restorationId
;
final
String
?
restorationId
;
/// {@macro flutter.widgets.shadow.scrollBehavior}
///
/// [ScrollBehavior]s also provide [ScrollPhysics]. If an explicit
/// [ScrollPhysics] is provided in [physics], it will take precedence,
/// followed by [scrollBehavior], and then the inherited ancestor
/// [ScrollBehavior].
///
/// The [ScrollBehavior] of the inherited [ScrollConfiguration] will be
/// modified by default to not apply a [Scrollbar]. This is because the
/// NestedScrollView cannot assume the configuration of the outer and inner
/// [Scrollable] widgets, particularly whether to treat them as one scrollable,
/// or separate and desirous of unique behaviors.
final
ScrollBehavior
?
scrollBehavior
;
/// Returns the [SliverOverlapAbsorberHandle] of the nearest ancestor
/// Returns the [SliverOverlapAbsorberHandle] of the nearest ancestor
/// [NestedScrollView].
/// [NestedScrollView].
///
///
...
@@ -613,6 +633,10 @@ class NestedScrollViewState extends State<NestedScrollView> {
...
@@ -613,6 +633,10 @@ class NestedScrollViewState extends State<NestedScrollView> {
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
final
ScrollPhysics
_scrollPhysics
=
widget
.
physics
?.
applyTo
(
const
ClampingScrollPhysics
())
??
widget
.
scrollBehavior
?.
getScrollPhysics
(
context
).
applyTo
(
const
ClampingScrollPhysics
())
??
const
ClampingScrollPhysics
();
return
_InheritedNestedScrollView
(
return
_InheritedNestedScrollView
(
state:
this
,
state:
this
,
child:
Builder
(
child:
Builder
(
...
@@ -622,9 +646,8 @@ class NestedScrollViewState extends State<NestedScrollView> {
...
@@ -622,9 +646,8 @@ class NestedScrollViewState extends State<NestedScrollView> {
dragStartBehavior:
widget
.
dragStartBehavior
,
dragStartBehavior:
widget
.
dragStartBehavior
,
scrollDirection:
widget
.
scrollDirection
,
scrollDirection:
widget
.
scrollDirection
,
reverse:
widget
.
reverse
,
reverse:
widget
.
reverse
,
physics:
widget
.
physics
!=
null
physics:
_scrollPhysics
,
?
widget
.
physics
!.
applyTo
(
const
ClampingScrollPhysics
())
scrollBehavior:
widget
.
scrollBehavior
??
ScrollConfiguration
.
of
(
context
).
copyWith
(
scrollbars:
false
),
:
const
ClampingScrollPhysics
(),
controller:
_coordinator
!.
_outerController
,
controller:
_coordinator
!.
_outerController
,
slivers:
widget
.
_buildSlivers
(
slivers:
widget
.
_buildSlivers
(
context
,
context
,
...
@@ -646,6 +669,7 @@ class _NestedScrollViewCustomScrollView extends CustomScrollView {
...
@@ -646,6 +669,7 @@ class _NestedScrollViewCustomScrollView extends CustomScrollView {
required
Axis
scrollDirection
,
required
Axis
scrollDirection
,
required
bool
reverse
,
required
bool
reverse
,
required
ScrollPhysics
physics
,
required
ScrollPhysics
physics
,
required
ScrollBehavior
scrollBehavior
,
required
ScrollController
controller
,
required
ScrollController
controller
,
required
List
<
Widget
>
slivers
,
required
List
<
Widget
>
slivers
,
required
this
.
handle
,
required
this
.
handle
,
...
@@ -656,6 +680,7 @@ class _NestedScrollViewCustomScrollView extends CustomScrollView {
...
@@ -656,6 +680,7 @@ class _NestedScrollViewCustomScrollView extends CustomScrollView {
scrollDirection:
scrollDirection
,
scrollDirection:
scrollDirection
,
reverse:
reverse
,
reverse:
reverse
,
physics:
physics
,
physics:
physics
,
scrollBehavior:
scrollBehavior
,
controller:
controller
,
controller:
controller
,
slivers:
slivers
,
slivers:
slivers
,
dragStartBehavior:
dragStartBehavior
,
dragStartBehavior:
dragStartBehavior
,
...
...
packages/flutter/lib/src/widgets/overscroll_indicator.dart
View file @
e40610d6
...
@@ -27,7 +27,7 @@ import 'ticker_provider.dart';
...
@@ -27,7 +27,7 @@ import 'ticker_provider.dart';
/// showing the indication, call [OverscrollIndicatorNotification.disallowGlow]
/// showing the indication, call [OverscrollIndicatorNotification.disallowGlow]
/// on the notification.
/// on the notification.
///
///
/// Created automatically by [ScrollBehavior.build
ViewportChrome
] on platforms
/// Created automatically by [ScrollBehavior.build
OverscrollIndicator
] on platforms
/// (e.g., Android) that commonly use this type of overscroll indication.
/// (e.g., Android) that commonly use this type of overscroll indication.
///
///
/// In a [MaterialApp], the edge glow color is the overall theme's
/// In a [MaterialApp], the edge glow color is the overall theme's
...
@@ -189,7 +189,7 @@ class GlowingOverscrollIndicator extends StatefulWidget {
...
@@ -189,7 +189,7 @@ class GlowingOverscrollIndicator extends StatefulWidget {
/// subtree) should include a source of [ScrollNotification] notifications.
/// subtree) should include a source of [ScrollNotification] notifications.
///
///
/// Typically a [GlowingOverscrollIndicator] is created by a
/// Typically a [GlowingOverscrollIndicator] is created by a
/// [ScrollBehavior.build
ViewportChrome
] method, in which case
/// [ScrollBehavior.build
OverscrollIndicator
] method, in which case
/// the child is usually the one provided as an argument to that method.
/// the child is usually the one provided as an argument to that method.
final
Widget
?
child
;
final
Widget
?
child
;
...
...
packages/flutter/lib/src/widgets/page_view.dart
View file @
e40610d6
...
@@ -13,6 +13,7 @@ import 'debug.dart';
...
@@ -13,6 +13,7 @@ import 'debug.dart';
import
'framework.dart'
;
import
'framework.dart'
;
import
'notification_listener.dart'
;
import
'notification_listener.dart'
;
import
'page_storage.dart'
;
import
'page_storage.dart'
;
import
'scroll_configuration.dart'
;
import
'scroll_context.dart'
;
import
'scroll_context.dart'
;
import
'scroll_controller.dart'
;
import
'scroll_controller.dart'
;
import
'scroll_metrics.dart'
;
import
'scroll_metrics.dart'
;
...
@@ -635,6 +636,7 @@ class PageView extends StatefulWidget {
...
@@ -635,6 +636,7 @@ class PageView extends StatefulWidget {
this
.
allowImplicitScrolling
=
false
,
this
.
allowImplicitScrolling
=
false
,
this
.
restorationId
,
this
.
restorationId
,
this
.
clipBehavior
=
Clip
.
hardEdge
,
this
.
clipBehavior
=
Clip
.
hardEdge
,
this
.
scrollBehavior
,
})
:
assert
(
allowImplicitScrolling
!=
null
),
})
:
assert
(
allowImplicitScrolling
!=
null
),
assert
(
clipBehavior
!=
null
),
assert
(
clipBehavior
!=
null
),
controller
=
controller
??
_defaultPageController
,
controller
=
controller
??
_defaultPageController
,
...
@@ -673,6 +675,7 @@ class PageView extends StatefulWidget {
...
@@ -673,6 +675,7 @@ class PageView extends StatefulWidget {
this
.
allowImplicitScrolling
=
false
,
this
.
allowImplicitScrolling
=
false
,
this
.
restorationId
,
this
.
restorationId
,
this
.
clipBehavior
=
Clip
.
hardEdge
,
this
.
clipBehavior
=
Clip
.
hardEdge
,
this
.
scrollBehavior
,
})
:
assert
(
allowImplicitScrolling
!=
null
),
})
:
assert
(
allowImplicitScrolling
!=
null
),
assert
(
clipBehavior
!=
null
),
assert
(
clipBehavior
!=
null
),
controller
=
controller
??
_defaultPageController
,
controller
=
controller
??
_defaultPageController
,
...
@@ -776,6 +779,7 @@ class PageView extends StatefulWidget {
...
@@ -776,6 +779,7 @@ class PageView extends StatefulWidget {
this
.
allowImplicitScrolling
=
false
,
this
.
allowImplicitScrolling
=
false
,
this
.
restorationId
,
this
.
restorationId
,
this
.
clipBehavior
=
Clip
.
hardEdge
,
this
.
clipBehavior
=
Clip
.
hardEdge
,
this
.
scrollBehavior
,
})
:
assert
(
childrenDelegate
!=
null
),
})
:
assert
(
childrenDelegate
!=
null
),
assert
(
allowImplicitScrolling
!=
null
),
assert
(
allowImplicitScrolling
!=
null
),
assert
(
clipBehavior
!=
null
),
assert
(
clipBehavior
!=
null
),
...
@@ -829,6 +833,10 @@ class PageView extends StatefulWidget {
...
@@ -829,6 +833,10 @@ class PageView extends StatefulWidget {
/// The physics are modified to snap to page boundaries using
/// The physics are modified to snap to page boundaries using
/// [PageScrollPhysics] prior to being used.
/// [PageScrollPhysics] prior to being used.
///
///
/// If an explicit [ScrollBehavior] is provided to [scrollBehavior], the
/// [ScrollPhysics] provided by that behavior will take precedence after
/// [physics].
///
/// Defaults to matching platform conventions.
/// Defaults to matching platform conventions.
final
ScrollPhysics
?
physics
;
final
ScrollPhysics
?
physics
;
...
@@ -854,6 +862,17 @@ class PageView extends StatefulWidget {
...
@@ -854,6 +862,17 @@ class PageView extends StatefulWidget {
/// Defaults to [Clip.hardEdge].
/// Defaults to [Clip.hardEdge].
final
Clip
clipBehavior
;
final
Clip
clipBehavior
;
/// {@macro flutter.widgets.shadow.scrollBehavior}
///
/// [ScrollBehavior]s also provide [ScrollPhysics]. If an explicit
/// [ScrollPhysics] is provided in [physics], it will take precedence,
/// followed by [scrollBehavior], and then the inherited ancestor
/// [ScrollBehavior].
///
/// The [ScrollBehavior] of the inherited [ScrollConfiguration] will be
/// modified by default to not apply a [Scrollbar].
final
ScrollBehavior
?
scrollBehavior
;
@override
@override
_PageViewState
createState
()
=>
_PageViewState
();
_PageViewState
createState
()
=>
_PageViewState
();
}
}
...
@@ -885,8 +904,8 @@ class _PageViewState extends State<PageView> {
...
@@ -885,8 +904,8 @@ class _PageViewState extends State<PageView> {
final
ScrollPhysics
physics
=
_ForceImplicitScrollPhysics
(
final
ScrollPhysics
physics
=
_ForceImplicitScrollPhysics
(
allowImplicitScrolling:
widget
.
allowImplicitScrolling
,
allowImplicitScrolling:
widget
.
allowImplicitScrolling
,
).
applyTo
(
widget
.
pageSnapping
).
applyTo
(
widget
.
pageSnapping
?
_kPagePhysics
.
applyTo
(
widget
.
physics
)
?
_kPagePhysics
.
applyTo
(
widget
.
physics
??
widget
.
scrollBehavior
?.
getScrollPhysics
(
context
)
)
:
widget
.
physics
);
:
widget
.
physics
??
widget
.
scrollBehavior
?.
getScrollPhysics
(
context
)
);
return
NotificationListener
<
ScrollNotification
>(
return
NotificationListener
<
ScrollNotification
>(
onNotification:
(
ScrollNotification
notification
)
{
onNotification:
(
ScrollNotification
notification
)
{
...
@@ -906,6 +925,7 @@ class _PageViewState extends State<PageView> {
...
@@ -906,6 +925,7 @@ class _PageViewState extends State<PageView> {
controller:
widget
.
controller
,
controller:
widget
.
controller
,
physics:
physics
,
physics:
physics
,
restorationId:
widget
.
restorationId
,
restorationId:
widget
.
restorationId
,
scrollBehavior:
widget
.
scrollBehavior
??
ScrollConfiguration
.
of
(
context
).
copyWith
(
scrollbars:
false
),
viewportBuilder:
(
BuildContext
context
,
ViewportOffset
position
)
{
viewportBuilder:
(
BuildContext
context
,
ViewportOffset
position
)
{
return
Viewport
(
return
Viewport
(
// TODO(dnfield): we should provide a way to set cacheExtent
// TODO(dnfield): we should provide a way to set cacheExtent
...
...
packages/flutter/lib/src/widgets/scroll_configuration.dart
View file @
e40610d6
...
@@ -9,6 +9,8 @@ import 'package:flutter/rendering.dart';
...
@@ -9,6 +9,8 @@ import 'package:flutter/rendering.dart';
import
'framework.dart'
;
import
'framework.dart'
;
import
'overscroll_indicator.dart'
;
import
'overscroll_indicator.dart'
;
import
'scroll_physics.dart'
;
import
'scroll_physics.dart'
;
import
'scrollable.dart'
;
import
'scrollbar.dart'
;
const
Color
_kDefaultGlowColor
=
Color
(
0xFFFFFFFF
);
const
Color
_kDefaultGlowColor
=
Color
(
0xFFFFFFFF
);
...
@@ -21,8 +23,13 @@ const Color _kDefaultGlowColor = Color(0xFFFFFFFF);
...
@@ -21,8 +23,13 @@ const Color _kDefaultGlowColor = Color(0xFFFFFFFF);
/// This class can be extended to further customize a [ScrollBehavior] for a
/// This class can be extended to further customize a [ScrollBehavior] for a
/// subtree. For example, overriding [ScrollBehavior.getScrollPhysics] sets the
/// subtree. For example, overriding [ScrollBehavior.getScrollPhysics] sets the
/// default [ScrollPhysics] for [Scrollable]s that inherit this [ScrollConfiguration].
/// default [ScrollPhysics] for [Scrollable]s that inherit this [ScrollConfiguration].
/// Overriding [ScrollBehavior.buildViewportChrome] can be used to add or change
/// Overriding [ScrollBehavior.buildOverscrollIndicator] can be used to add or change
/// default decorations like [GlowingOverscrollIndicator]s.
/// the default [GlowingOverscrollIndicator] decoration, while
/// [ScrollBehavior.buildScrollbar] can be changed to modify the default [Scrollbar].
///
/// When looking to easily toggle the default decorations, you can use
/// [ScrollBehavior.copyWith] instead of creating your own [ScrollBehavior] class.
/// The `scrollbar` and `overscrollIndicator` flags can turn these decorations off.
/// {@endtemplate}
/// {@endtemplate}
///
///
/// See also:
/// See also:
...
@@ -34,6 +41,29 @@ class ScrollBehavior {
...
@@ -34,6 +41,29 @@ class ScrollBehavior {
/// Creates a description of how [Scrollable] widgets should behave.
/// Creates a description of how [Scrollable] widgets should behave.
const
ScrollBehavior
();
const
ScrollBehavior
();
/// Creates a copy of this ScrollBehavior, making it possible to
/// easily toggle `scrollbar` and `overscrollIndicator` effects.
///
/// This is used by widgets like [PageView] and [ListWheelScrollView] to
/// override the current [ScrollBehavior] and manage how they are decorated.
/// Widgets such as these have the option to provide a [ScrollBehavior] on
/// the widget level, like [PageView.scrollBehavior], in order to change the
/// default.
ScrollBehavior
copyWith
({
bool
scrollbars
=
true
,
bool
overscroll
=
true
,
ScrollPhysics
?
physics
,
TargetPlatform
?
platform
,
})
{
return
_WrappedScrollBehavior
(
delegate:
this
,
scrollbar:
scrollbars
,
overscrollIndicator:
overscroll
,
physics:
physics
,
platform:
platform
,
);
}
/// The platform whose scroll physics should be implemented.
/// The platform whose scroll physics should be implemented.
///
///
/// Defaults to the current platform.
/// Defaults to the current platform.
...
@@ -44,9 +74,14 @@ class ScrollBehavior {
...
@@ -44,9 +74,14 @@ class ScrollBehavior {
/// For example, on Android, this method wraps the given widget with a
/// For example, on Android, this method wraps the given widget with a
/// [GlowingOverscrollIndicator] to provide visual feedback when the user
/// [GlowingOverscrollIndicator] to provide visual feedback when the user
/// overscrolls.
/// overscrolls.
///
/// This method is deprecated. Use [ScrollBehavior.buildOverscrollIndicator]
/// instead.
@Deprecated
(
'Migrate to buildOverscrollIndicator. '
'This feature was deprecated after v2.1.0-11.0.pre.'
)
Widget
buildViewportChrome
(
BuildContext
context
,
Widget
child
,
AxisDirection
axisDirection
)
{
Widget
buildViewportChrome
(
BuildContext
context
,
Widget
child
,
AxisDirection
axisDirection
)
{
// When modifying this function, consider modifying the implementation in
// MaterialScrollBehavior as well.
switch
(
getPlatform
(
context
))
{
switch
(
getPlatform
(
context
))
{
case
TargetPlatform
.
iOS
:
case
TargetPlatform
.
iOS
:
case
TargetPlatform
.
linux
:
case
TargetPlatform
.
linux
:
...
@@ -63,6 +98,35 @@ class ScrollBehavior {
...
@@ -63,6 +98,35 @@ class ScrollBehavior {
}
}
}
}
/// Applies a [RawScrollbar] to the child widget on desktop platforms.
Widget
buildScrollbar
(
BuildContext
context
,
Widget
child
,
ScrollableDetails
details
)
{
// When modifying this function, consider modifying the implementation in
// the Material and Cupertino subclasses as well.
switch
(
getPlatform
(
context
))
{
case
TargetPlatform
.
linux
:
case
TargetPlatform
.
macOS
:
case
TargetPlatform
.
windows
:
return
RawScrollbar
(
child:
child
,
controller:
details
.
controller
,
);
case
TargetPlatform
.
android
:
case
TargetPlatform
.
fuchsia
:
case
TargetPlatform
.
iOS
:
return
child
;
}
}
/// Applies a [GlowingOverscrollIndicator] to the child widget on
/// [TargetPlatform.android] and [TargetPlatform.fuchsia].
Widget
buildOverscrollIndicator
(
BuildContext
context
,
Widget
child
,
ScrollableDetails
details
)
{
// TODO(Piinks): Move implementation from buildViewportChrome here after
// deprecation period
// When modifying this function, consider modifying the implementation in
// the Material and Cupertino subclasses as well.
return
buildViewportChrome
(
context
,
child
,
details
.
direction
);
}
/// Specifies the type of velocity tracker to use in the descendant
/// Specifies the type of velocity tracker to use in the descendant
/// [Scrollable]s' drag gesture recognizers, for estimating the velocity of a
/// [Scrollable]s' drag gesture recognizers, for estimating the velocity of a
/// drag gesture.
/// drag gesture.
...
@@ -129,6 +193,84 @@ class ScrollBehavior {
...
@@ -129,6 +193,84 @@ class ScrollBehavior {
String
toString
()
=>
objectRuntimeType
(
this
,
'ScrollBehavior'
);
String
toString
()
=>
objectRuntimeType
(
this
,
'ScrollBehavior'
);
}
}
class
_WrappedScrollBehavior
implements
ScrollBehavior
{
const
_WrappedScrollBehavior
({
required
this
.
delegate
,
this
.
scrollbar
=
true
,
this
.
overscrollIndicator
=
true
,
this
.
physics
,
this
.
platform
,
});
final
ScrollBehavior
delegate
;
final
bool
scrollbar
;
final
bool
overscrollIndicator
;
final
ScrollPhysics
?
physics
;
final
TargetPlatform
?
platform
;
@override
Widget
buildOverscrollIndicator
(
BuildContext
context
,
Widget
child
,
ScrollableDetails
details
)
{
if
(
overscrollIndicator
)
return
delegate
.
buildOverscrollIndicator
(
context
,
child
,
details
);
return
child
;
}
@override
Widget
buildScrollbar
(
BuildContext
context
,
Widget
child
,
ScrollableDetails
details
)
{
if
(
scrollbar
)
return
delegate
.
buildScrollbar
(
context
,
child
,
details
);
return
child
;
}
@override
Widget
buildViewportChrome
(
BuildContext
context
,
Widget
child
,
AxisDirection
axisDirection
)
{
return
delegate
.
buildViewportChrome
(
context
,
child
,
axisDirection
);
}
@override
ScrollBehavior
copyWith
({
bool
scrollbars
=
true
,
bool
overscroll
=
true
,
ScrollPhysics
?
physics
,
TargetPlatform
?
platform
,
})
{
return
delegate
.
copyWith
(
scrollbars:
scrollbars
,
overscroll:
overscroll
,
physics:
physics
,
platform:
platform
,
);
}
@override
TargetPlatform
getPlatform
(
BuildContext
context
)
{
return
platform
??
delegate
.
getPlatform
(
context
);
}
@override
ScrollPhysics
getScrollPhysics
(
BuildContext
context
)
{
return
physics
??
delegate
.
getScrollPhysics
(
context
);
}
@override
bool
shouldNotify
(
_WrappedScrollBehavior
oldDelegate
)
{
return
oldDelegate
.
delegate
.
runtimeType
!=
delegate
.
runtimeType
||
oldDelegate
.
scrollbar
!=
scrollbar
||
oldDelegate
.
overscrollIndicator
!=
overscrollIndicator
||
oldDelegate
.
physics
!=
physics
||
oldDelegate
.
platform
!=
platform
||
delegate
.
shouldNotify
(
oldDelegate
.
delegate
);
}
@override
GestureVelocityTrackerBuilder
velocityTrackerBuilder
(
BuildContext
context
)
{
return
delegate
.
velocityTrackerBuilder
(
context
);
}
@override
String
toString
()
=>
objectRuntimeType
(
this
,
'_WrappedScrollBehavior'
);
}
/// Controls how [Scrollable] widgets behave in a subtree.
/// Controls how [Scrollable] widgets behave in a subtree.
///
///
/// The scroll configuration determines the [ScrollPhysics] and viewport
/// The scroll configuration determines the [ScrollPhysics] and viewport
...
...
packages/flutter/lib/src/widgets/scroll_context.dart
View file @
e40610d6
...
@@ -24,7 +24,7 @@ abstract class ScrollContext {
...
@@ -24,7 +24,7 @@ abstract class ScrollContext {
/// This context is typically different that the context of the scrollable
/// This context is typically different that the context of the scrollable
/// widget itself. For example, [Scrollable] uses a context outside the
/// widget itself. For example, [Scrollable] uses a context outside the
/// [Viewport] but inside the widgets created by
/// [Viewport] but inside the widgets created by
/// [ScrollBehavior.build
ViewportChrome
].
/// [ScrollBehavior.build
OverscrollIndicator] and [ScrollBehavior.buildScrollbar
].
BuildContext
?
get
notificationContext
;
BuildContext
?
get
notificationContext
;
/// The [BuildContext] that should be used when searching for a [PageStorage].
/// The [BuildContext] that should be used when searching for a [PageStorage].
...
...
packages/flutter/lib/src/widgets/scroll_view.dart
View file @
e40610d6
...
@@ -15,6 +15,7 @@ import 'framework.dart';
...
@@ -15,6 +15,7 @@ import 'framework.dart';
import
'media_query.dart'
;
import
'media_query.dart'
;
import
'notification_listener.dart'
;
import
'notification_listener.dart'
;
import
'primary_scroll_controller.dart'
;
import
'primary_scroll_controller.dart'
;
import
'scroll_configuration.dart'
;
import
'scroll_controller.dart'
;
import
'scroll_controller.dart'
;
import
'scroll_notification.dart'
;
import
'scroll_notification.dart'
;
import
'scroll_physics.dart'
;
import
'scroll_physics.dart'
;
...
@@ -83,6 +84,7 @@ abstract class ScrollView extends StatelessWidget {
...
@@ -83,6 +84,7 @@ abstract class ScrollView extends StatelessWidget {
this
.
controller
,
this
.
controller
,
bool
?
primary
,
bool
?
primary
,
ScrollPhysics
?
physics
,
ScrollPhysics
?
physics
,
this
.
scrollBehavior
,
this
.
shrinkWrap
=
false
,
this
.
shrinkWrap
=
false
,
this
.
center
,
this
.
center
,
this
.
anchor
=
0.0
,
this
.
anchor
=
0.0
,
...
@@ -205,8 +207,20 @@ abstract class ScrollView extends StatelessWidget {
...
@@ -205,8 +207,20 @@ abstract class ScrollView extends StatelessWidget {
/// inefficient to speculatively create this object each frame to see if the
/// inefficient to speculatively create this object each frame to see if the
/// physics should be updated.)
/// physics should be updated.)
/// {@endtemplate}
/// {@endtemplate}
///
/// If an explicit [ScrollBehavior] is provided to [scrollBehavior], the
/// [ScrollPhysics] provided by that behavior will take precedence after
/// [physics].
final
ScrollPhysics
?
physics
;
final
ScrollPhysics
?
physics
;
/// {@macro flutter.widgets.shadow.scrollBehavior}
///
/// [ScrollBehavior]s also provide [ScrollPhysics]. If an explicit
/// [ScrollPhysics] is provided in [physics], it will take precedence,
/// followed by [scrollBehavior], and then the inherited ancestor
/// [ScrollBehavior].
final
ScrollBehavior
?
scrollBehavior
;
/// {@template flutter.widgets.scroll_view.shrinkWrap}
/// {@template flutter.widgets.scroll_view.shrinkWrap}
/// Whether the extent of the scroll view in the [scrollDirection] should be
/// Whether the extent of the scroll view in the [scrollDirection] should be
/// determined by the contents being viewed.
/// determined by the contents being viewed.
...
@@ -380,6 +394,7 @@ abstract class ScrollView extends StatelessWidget {
...
@@ -380,6 +394,7 @@ abstract class ScrollView extends StatelessWidget {
axisDirection:
axisDirection
,
axisDirection:
axisDirection
,
controller:
scrollController
,
controller:
scrollController
,
physics:
physics
,
physics:
physics
,
scrollBehavior:
scrollBehavior
,
semanticChildCount:
semanticChildCount
,
semanticChildCount:
semanticChildCount
,
restorationId:
restorationId
,
restorationId:
restorationId
,
viewportBuilder:
(
BuildContext
context
,
ViewportOffset
offset
)
{
viewportBuilder:
(
BuildContext
context
,
ViewportOffset
offset
)
{
...
@@ -610,6 +625,7 @@ class CustomScrollView extends ScrollView {
...
@@ -610,6 +625,7 @@ class CustomScrollView extends ScrollView {
ScrollController
?
controller
,
ScrollController
?
controller
,
bool
?
primary
,
bool
?
primary
,
ScrollPhysics
?
physics
,
ScrollPhysics
?
physics
,
ScrollBehavior
?
scrollBehavior
,
bool
shrinkWrap
=
false
,
bool
shrinkWrap
=
false
,
Key
?
center
,
Key
?
center
,
double
anchor
=
0.0
,
double
anchor
=
0.0
,
...
@@ -627,6 +643,7 @@ class CustomScrollView extends ScrollView {
...
@@ -627,6 +643,7 @@ class CustomScrollView extends ScrollView {
controller:
controller
,
controller:
controller
,
primary:
primary
,
primary:
primary
,
physics:
physics
,
physics:
physics
,
scrollBehavior:
scrollBehavior
,
shrinkWrap:
shrinkWrap
,
shrinkWrap:
shrinkWrap
,
center:
center
,
center:
center
,
anchor:
anchor
,
anchor:
anchor
,
...
...
packages/flutter/lib/src/widgets/scrollable.dart
View file @
e40610d6
...
@@ -25,7 +25,6 @@ import 'scroll_controller.dart';
...
@@ -25,7 +25,6 @@ import 'scroll_controller.dart';
import
'scroll_metrics.dart'
;
import
'scroll_metrics.dart'
;
import
'scroll_physics.dart'
;
import
'scroll_physics.dart'
;
import
'scroll_position.dart'
;
import
'scroll_position.dart'
;
import
'scroll_position_with_single_context.dart'
;
import
'ticker_provider.dart'
;
import
'ticker_provider.dart'
;
import
'viewport.dart'
;
import
'viewport.dart'
;
...
@@ -91,6 +90,7 @@ class Scrollable extends StatefulWidget {
...
@@ -91,6 +90,7 @@ class Scrollable extends StatefulWidget {
this
.
semanticChildCount
,
this
.
semanticChildCount
,
this
.
dragStartBehavior
=
DragStartBehavior
.
start
,
this
.
dragStartBehavior
=
DragStartBehavior
.
start
,
this
.
restorationId
,
this
.
restorationId
,
this
.
scrollBehavior
,
})
:
assert
(
axisDirection
!=
null
),
})
:
assert
(
axisDirection
!=
null
),
assert
(
dragStartBehavior
!=
null
),
assert
(
dragStartBehavior
!=
null
),
assert
(
viewportBuilder
!=
null
),
assert
(
viewportBuilder
!=
null
),
...
@@ -135,6 +135,10 @@ class Scrollable extends StatefulWidget {
...
@@ -135,6 +135,10 @@ class Scrollable extends StatefulWidget {
/// Defaults to matching platform conventions via the physics provided from
/// Defaults to matching platform conventions via the physics provided from
/// the ambient [ScrollConfiguration].
/// the ambient [ScrollConfiguration].
///
///
/// If an explicit [ScrollBehavior] is provided to [scrollBehavior], the
/// [ScrollPhysics] provided by that behavior will take precedence after
/// [physics].
///
/// The physics can be changed dynamically, but new physics will only take
/// The physics can be changed dynamically, but new physics will only take
/// effect if the _class_ of the provided object changes. Merely constructing
/// effect if the _class_ of the provided object changes. Merely constructing
/// a new instance with a different configuration is insufficient to cause the
/// a new instance with a different configuration is insufficient to cause the
...
@@ -243,6 +247,14 @@ class Scrollable extends StatefulWidget {
...
@@ -243,6 +247,14 @@ class Scrollable extends StatefulWidget {
/// {@endtemplate}
/// {@endtemplate}
final
String
?
restorationId
;
final
String
?
restorationId
;
/// {@macro flutter.widgets.shadow.scrollBehavior}
///
/// [ScrollBehavior]s also provide [ScrollPhysics]. If an explicit
/// [ScrollPhysics] is provided in [physics], it will take precedence,
/// followed by [scrollBehavior], and then the inherited ancestor
/// [ScrollBehavior].
final
ScrollBehavior
?
scrollBehavior
;
/// The axis along which the scroll view scrolls.
/// The axis along which the scroll view scrolls.
///
///
/// Determined by the [axisDirection].
/// Determined by the [axisDirection].
...
@@ -385,27 +397,31 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
...
@@ -385,27 +397,31 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
late
ScrollBehavior
_configuration
;
late
ScrollBehavior
_configuration
;
ScrollPhysics
?
_physics
;
ScrollPhysics
?
_physics
;
ScrollController
?
_fallbackScrollController
;
ScrollController
get
_effectiveScrollController
=>
widget
.
controller
??
_fallbackScrollController
!;
// Only call this from places that will definitely trigger a rebuild.
// Only call this from places that will definitely trigger a rebuild.
void
_updatePosition
()
{
void
_updatePosition
()
{
_configuration
=
ScrollConfiguration
.
of
(
context
);
_configuration
=
widget
.
scrollBehavior
??
ScrollConfiguration
.
of
(
context
);
_physics
=
_configuration
.
getScrollPhysics
(
context
);
_physics
=
_configuration
.
getScrollPhysics
(
context
);
if
(
widget
.
physics
!=
null
)
if
(
widget
.
physics
!=
null
)
{
_physics
=
widget
.
physics
!.
applyTo
(
_physics
);
_physics
=
widget
.
physics
!.
applyTo
(
_physics
);
final
ScrollController
?
controller
=
widget
.
controller
;
}
else
if
(
widget
.
scrollBehavior
!=
null
)
{
_physics
=
widget
.
scrollBehavior
!.
getScrollPhysics
(
context
).
applyTo
(
_physics
);
}
final
ScrollPosition
?
oldPosition
=
_position
;
final
ScrollPosition
?
oldPosition
=
_position
;
if
(
oldPosition
!=
null
)
{
if
(
oldPosition
!=
null
)
{
controller
?
.
detach
(
oldPosition
);
_effectiveScrollController
.
detach
(
oldPosition
);
// It's important that we not dispose the old position until after the
// It's important that we not dispose the old position until after the
// viewport has had a chance to unregister its listeners from the old
// viewport has had a chance to unregister its listeners from the old
// position. So, schedule a microtask to do it.
// position. So, schedule a microtask to do it.
scheduleMicrotask
(
oldPosition
.
dispose
);
scheduleMicrotask
(
oldPosition
.
dispose
);
}
}
_position
=
controller
?.
createScrollPosition
(
_physics
!,
this
,
oldPosition
)
_position
=
_effectiveScrollController
.
createScrollPosition
(
_physics
!,
this
,
oldPosition
);
??
ScrollPositionWithSingleContext
(
physics:
_physics
!,
context:
this
,
oldPosition:
oldPosition
);
assert
(
_position
!=
null
);
assert
(
_position
!=
null
);
controller
?
.
attach
(
position
);
_effectiveScrollController
.
attach
(
position
);
}
}
@override
@override
...
@@ -426,6 +442,13 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
...
@@ -426,6 +442,13 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
ServicesBinding
.
instance
!.
restorationManager
.
flushData
();
ServicesBinding
.
instance
!.
restorationManager
.
flushData
();
}
}
@override
void
initState
()
{
if
(
widget
.
controller
==
null
)
_fallbackScrollController
=
ScrollController
();
super
.
initState
();
}
@override
@override
void
didChangeDependencies
()
{
void
didChangeDependencies
()
{
_updatePosition
();
_updatePosition
();
...
@@ -433,8 +456,8 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
...
@@ -433,8 +456,8 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
}
}
bool
_shouldUpdatePosition
(
Scrollable
oldWidget
)
{
bool
_shouldUpdatePosition
(
Scrollable
oldWidget
)
{
ScrollPhysics
?
newPhysics
=
widget
.
physics
;
ScrollPhysics
?
newPhysics
=
widget
.
physics
??
widget
.
scrollBehavior
?.
getScrollPhysics
(
context
)
;
ScrollPhysics
?
oldPhysics
=
oldWidget
.
physics
;
ScrollPhysics
?
oldPhysics
=
oldWidget
.
physics
??
oldWidget
.
scrollBehavior
?.
getScrollPhysics
(
context
)
;
do
{
do
{
if
(
newPhysics
?.
runtimeType
!=
oldPhysics
?.
runtimeType
)
if
(
newPhysics
?.
runtimeType
!=
oldPhysics
?.
runtimeType
)
return
true
;
return
true
;
...
@@ -450,8 +473,25 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
...
@@ -450,8 +473,25 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
super
.
didUpdateWidget
(
oldWidget
);
super
.
didUpdateWidget
(
oldWidget
);
if
(
widget
.
controller
!=
oldWidget
.
controller
)
{
if
(
widget
.
controller
!=
oldWidget
.
controller
)
{
if
(
oldWidget
.
controller
==
null
)
{
// The old controller was null, meaning the fallback cannot be null.
// Dispose of the fallback.
assert
(
_fallbackScrollController
!=
null
);
assert
(
widget
.
controller
!=
null
);
_fallbackScrollController
!.
detach
(
position
);
_fallbackScrollController
!.
dispose
();
_fallbackScrollController
=
null
;
}
else
{
// The old controller was not null, detach.
oldWidget
.
controller
?.
detach
(
position
);
oldWidget
.
controller
?.
detach
(
position
);
widget
.
controller
?.
attach
(
position
);
if
(
widget
.
controller
==
null
)
{
// If the new controller is null, we need to set up the fallback
// ScrollController.
_fallbackScrollController
=
ScrollController
();
}
}
// Attach the updated effective scroll controller.
_effectiveScrollController
.
attach
(
position
);
}
}
if
(
_shouldUpdatePosition
(
oldWidget
))
if
(
_shouldUpdatePosition
(
oldWidget
))
...
@@ -460,7 +500,13 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
...
@@ -460,7 +500,13 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
@override
@override
void
dispose
()
{
void
dispose
()
{
widget
.
controller
?.
detach
(
position
);
if
(
widget
.
controller
!=
null
)
{
widget
.
controller
!.
detach
(
position
);
}
else
{
_fallbackScrollController
?.
detach
(
position
);
_fallbackScrollController
?.
dispose
();
}
position
.
dispose
();
position
.
dispose
();
_persistedScrollOffset
.
dispose
();
_persistedScrollOffset
.
dispose
();
super
.
dispose
();
super
.
dispose
();
...
@@ -717,7 +763,16 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
...
@@ -717,7 +763,16 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
);
);
}
}
return
_configuration
.
buildViewportChrome
(
context
,
result
,
widget
.
axisDirection
);
final
ScrollableDetails
details
=
ScrollableDetails
(
direction:
widget
.
axisDirection
,
controller:
_effectiveScrollController
,
);
return
_configuration
.
buildScrollbar
(
context
,
_configuration
.
buildOverscrollIndicator
(
context
,
result
,
details
),
details
,
);
}
}
@override
@override
...
@@ -731,6 +786,33 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
...
@@ -731,6 +786,33 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin, R
String
?
get
restorationId
=>
widget
.
restorationId
;
String
?
get
restorationId
=>
widget
.
restorationId
;
}
}
/// Describes the aspects of a Scrollable widget to inform inherited widgets
/// like [ScrollBehavior] for decorating.
///
/// Decorations like [GlowingOverscrollIndicator]s and [Scrollbar]s require
/// information about the Scrollable in order to be initialized.
@immutable
class
ScrollableDetails
{
/// Creates a set of details describing the [Scrollable]. The [direction]
/// cannot be null.
const
ScrollableDetails
({
required
this
.
direction
,
required
this
.
controller
,
});
/// The direction in which this widget scrolls.
///
/// Cannot be null.
final
AxisDirection
direction
;
/// A [ScrollController] that can be used to control the position of the
/// [Scrollable] widget.
///
/// This can be used by [ScrollBehavior] to apply a [Scrollbar] to the associated
/// [Scrollable].
final
ScrollController
controller
;
}
/// With [_ScrollSemantics] certain child [SemanticsNode]s can be
/// With [_ScrollSemantics] certain child [SemanticsNode]s can be
/// excluded from the scrollable area for semantics purposes.
/// excluded from the scrollable area for semantics purposes.
///
///
...
...
packages/flutter/lib/src/widgets/scrollbar.dart
View file @
e40610d6
...
@@ -584,7 +584,8 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
...
@@ -584,7 +584,8 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
///
///
/// If the scrollbar is wrapped around multiple [ScrollView]s, it only responds to
/// If the scrollbar is wrapped around multiple [ScrollView]s, it only responds to
/// the nearest scrollView and shows the corresponding scrollbar thumb by default.
/// the nearest scrollView and shows the corresponding scrollbar thumb by default.
/// Set [notificationPredicate] to something else for more complicated behaviors.
/// The [notificationPredicate] allows the ability to customize which
/// [ScrollNotification]s the Scrollbar should listen to.
///
///
/// Scrollbars are interactive and will also use the [PrimaryScrollController] if
/// Scrollbars are interactive and will also use the [PrimaryScrollController] if
/// a [controller] is not set. Scrollbar thumbs can be dragged along the main axis
/// a [controller] is not set. Scrollbar thumbs can be dragged along the main axis
...
@@ -596,6 +597,17 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
...
@@ -596,6 +597,17 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
/// painted. In this case, the scrollbar cannot accurately represent the
/// painted. In this case, the scrollbar cannot accurately represent the
/// relative location of the visible area, or calculate the accurate delta to
/// relative location of the visible area, or calculate the accurate delta to
/// apply when dragging on the thumb or tapping on the track.
/// apply when dragging on the thumb or tapping on the track.
///
/// Scrollbars are added to most [Scrollable] widgets by default on Desktop
/// platforms in [ScrollBehavior.buildScrollbar] as part of an app's
/// [ScrollConfiguration]. Scrollable widgets that do not have automatically
/// applied Scrollbars include
///
/// * [EditableText]
/// * [ListWheelScrollView]
/// * [PageView]
/// * [NestedScrollView]
/// * [DropdownButton]
/// {@endtemplate}
/// {@endtemplate}
///
///
// TODO(Piinks): Add code sample
// TODO(Piinks): Add code sample
...
@@ -615,8 +627,8 @@ class RawScrollbar extends StatefulWidget {
...
@@ -615,8 +627,8 @@ class RawScrollbar extends StatefulWidget {
/// The [child], or a descendant of the [child], should be a source of
/// The [child], or a descendant of the [child], should be a source of
/// [ScrollNotification] notifications, typically a [Scrollable] widget.
/// [ScrollNotification] notifications, typically a [Scrollable] widget.
///
///
/// The [child], [
thickness], [thumbColor], [isAlwaysShown], [fadeDuration],
/// The [child], [
fadeDuration], [pressDuration], and [timeToFade] arguments
///
and [timeToFade] arguments
must not be null.
/// must not be null.
const
RawScrollbar
({
const
RawScrollbar
({
Key
?
key
,
Key
?
key
,
required
this
.
child
,
required
this
.
child
,
...
@@ -641,6 +653,9 @@ class RawScrollbar extends StatefulWidget {
...
@@ -641,6 +653,9 @@ class RawScrollbar extends StatefulWidget {
///
///
/// The scrollbar will be stacked on top of this child. This child (and its
/// The scrollbar will be stacked on top of this child. This child (and its
/// subtree) should include a source of [ScrollNotification] notifications.
/// subtree) should include a source of [ScrollNotification] notifications.
/// Typically a [Scrollbar] is created on desktop platforms by a
/// [ScrollBehavior.buildScrollbar] method, in which case the child is usually
/// the one provided as an argument to that method.
///
///
/// Typically a [ListView] or [CustomScrollView].
/// Typically a [ListView] or [CustomScrollView].
/// {@endtemplate}
/// {@endtemplate}
...
...
packages/flutter/test/cupertino/app_test.dart
View file @
e40610d6
...
@@ -198,7 +198,7 @@ void main() {
...
@@ -198,7 +198,7 @@ void main() {
late
BuildContext
capturedContext
;
late
BuildContext
capturedContext
;
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
CupertinoApp
(
CupertinoApp
(
scrollBehavior:
MockScrollBehavior
(),
scrollBehavior:
const
MockScrollBehavior
(),
home:
Builder
(
home:
Builder
(
builder:
(
BuildContext
context
)
{
builder:
(
BuildContext
context
)
{
capturedContext
=
context
;
capturedContext
=
context
;
...
@@ -214,6 +214,8 @@ void main() {
...
@@ -214,6 +214,8 @@ void main() {
}
}
class
MockScrollBehavior
extends
ScrollBehavior
{
class
MockScrollBehavior
extends
ScrollBehavior
{
const
MockScrollBehavior
();
@override
@override
ScrollPhysics
getScrollPhysics
(
BuildContext
context
)
=>
const
NeverScrollableScrollPhysics
();
ScrollPhysics
getScrollPhysics
(
BuildContext
context
)
=>
const
NeverScrollableScrollPhysics
();
}
}
...
...
packages/flutter/test/cupertino/nav_bar_test.dart
View file @
e40610d6
...
@@ -956,7 +956,6 @@ void main() {
...
@@ -956,7 +956,6 @@ void main() {
},
},
);
);
testWidgets
(
'NavBar draws a light system bar for a dark background'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'NavBar draws a light system bar for a dark background'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
WidgetsApp
(
WidgetsApp
(
...
...
packages/flutter/test/cupertino/refresh_test.dart
View file @
e40610d6
...
@@ -34,9 +34,8 @@ void main() {
...
@@ -34,9 +34,8 @@ void main() {
void
uiTestGroup
()
{
void
uiTestGroup
()
{
testWidgets
(
"doesn't invoke anything without user interaction"
,
(
WidgetTester
tester
)
async
{
testWidgets
(
"doesn't invoke anything without user interaction"
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
CustomScrollView
(
child:
CustomScrollView
(
slivers:
<
Widget
>[
slivers:
<
Widget
>[
CupertinoSliverRefreshControl
(
CupertinoSliverRefreshControl
(
builder:
mockHelper
.
builder
,
builder:
mockHelper
.
builder
,
...
@@ -57,9 +56,8 @@ void main() {
...
@@ -57,9 +56,8 @@ void main() {
testWidgets
(
'calls the indicator builder when starting to overscroll'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'calls the indicator builder when starting to overscroll'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
CustomScrollView
(
child:
CustomScrollView
(
slivers:
<
Widget
>[
slivers:
<
Widget
>[
CupertinoSliverRefreshControl
(
CupertinoSliverRefreshControl
(
builder:
mockHelper
.
builder
,
builder:
mockHelper
.
builder
,
...
@@ -96,6 +94,8 @@ void main() {
...
@@ -96,6 +94,8 @@ void main() {
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
Directionality
(
textDirection:
TextDirection
.
ltr
,
textDirection:
TextDirection
.
ltr
,
child:
MediaQuery
(
data:
const
MediaQueryData
(),
child:
CustomScrollView
(
child:
CustomScrollView
(
slivers:
<
Widget
>[
slivers:
<
Widget
>[
CupertinoSliverRefreshControl
(
CupertinoSliverRefreshControl
(
...
@@ -105,6 +105,7 @@ void main() {
...
@@ -105,6 +105,7 @@ void main() {
],
],
),
),
),
),
),
);
);
// Drag down but not enough to trigger the refresh.
// Drag down but not enough to trigger the refresh.
...
@@ -121,9 +122,8 @@ void main() {
...
@@ -121,9 +122,8 @@ void main() {
testWidgets
(
'let the builder update as canceled drag scrolls away'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'let the builder update as canceled drag scrolls away'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
CustomScrollView
(
child:
CustomScrollView
(
slivers:
<
Widget
>[
slivers:
<
Widget
>[
CupertinoSliverRefreshControl
(
CupertinoSliverRefreshControl
(
builder:
mockHelper
.
builder
,
builder:
mockHelper
.
builder
,
...
@@ -178,9 +178,8 @@ void main() {
...
@@ -178,9 +178,8 @@ void main() {
});
});
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
CustomScrollView
(
child:
CustomScrollView
(
slivers:
<
Widget
>[
slivers:
<
Widget
>[
CupertinoSliverRefreshControl
(
CupertinoSliverRefreshControl
(
builder:
mockHelper
.
builder
,
builder:
mockHelper
.
builder
,
...
@@ -234,9 +233,8 @@ void main() {
...
@@ -234,9 +233,8 @@ void main() {
'refreshing task keeps the sliver expanded forever until done'
,
'refreshing task keeps the sliver expanded forever until done'
,
(
WidgetTester
tester
)
async
{
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
CustomScrollView
(
child:
CustomScrollView
(
slivers:
<
Widget
>[
slivers:
<
Widget
>[
CupertinoSliverRefreshControl
(
CupertinoSliverRefreshControl
(
builder:
mockHelper
.
builder
,
builder:
mockHelper
.
builder
,
...
@@ -308,9 +306,8 @@ void main() {
...
@@ -308,9 +306,8 @@ void main() {
()
async
{
()
async
{
mockHelper
.
refreshCompleter
=
Completer
<
void
>.
sync
();
mockHelper
.
refreshCompleter
=
Completer
<
void
>.
sync
();
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
CustomScrollView
(
child:
CustomScrollView
(
slivers:
<
Widget
>[
slivers:
<
Widget
>[
CupertinoSliverRefreshControl
(
CupertinoSliverRefreshControl
(
builder:
mockHelper
.
builder
,
builder:
mockHelper
.
builder
,
...
@@ -382,9 +379,8 @@ void main() {
...
@@ -382,9 +379,8 @@ void main() {
mockHelper
.
refreshIndicator
=
const
Center
(
child:
Text
(
'-1'
));
mockHelper
.
refreshIndicator
=
const
Center
(
child:
Text
(
'-1'
));
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
CustomScrollView
(
child:
CustomScrollView
(
slivers:
<
Widget
>[
slivers:
<
Widget
>[
CupertinoSliverRefreshControl
(
CupertinoSliverRefreshControl
(
builder:
mockHelper
.
builder
,
builder:
mockHelper
.
builder
,
...
@@ -456,9 +452,8 @@ void main() {
...
@@ -456,9 +452,8 @@ void main() {
mockHelper
.
refreshIndicator
=
const
Center
(
child:
Text
(
'-1'
));
mockHelper
.
refreshIndicator
=
const
Center
(
child:
Text
(
'-1'
));
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
CustomScrollView
(
child:
CustomScrollView
(
slivers:
<
Widget
>[
slivers:
<
Widget
>[
CupertinoSliverRefreshControl
(
CupertinoSliverRefreshControl
(
builder:
mockHelper
.
builder
,
builder:
mockHelper
.
builder
,
...
@@ -525,9 +520,8 @@ void main() {
...
@@ -525,9 +520,8 @@ void main() {
mockHelper
.
refreshIndicator
=
const
Center
(
child:
Text
(
'-1'
));
mockHelper
.
refreshIndicator
=
const
Center
(
child:
Text
(
'-1'
));
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
CustomScrollView
(
child:
CustomScrollView
(
slivers:
<
Widget
>[
slivers:
<
Widget
>[
CupertinoSliverRefreshControl
(
CupertinoSliverRefreshControl
(
builder:
mockHelper
.
builder
,
builder:
mockHelper
.
builder
,
...
@@ -608,9 +602,8 @@ void main() {
...
@@ -608,9 +602,8 @@ void main() {
mockHelper
.
refreshIndicator
=
const
Center
(
child:
Text
(
'-1'
));
mockHelper
.
refreshIndicator
=
const
Center
(
child:
Text
(
'-1'
));
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
CustomScrollView
(
child:
CustomScrollView
(
slivers:
<
Widget
>[
slivers:
<
Widget
>[
CupertinoSliverRefreshControl
(
CupertinoSliverRefreshControl
(
builder:
mockHelper
.
builder
,
builder:
mockHelper
.
builder
,
...
@@ -689,9 +682,8 @@ void main() {
...
@@ -689,9 +682,8 @@ void main() {
mockHelper
.
refreshIndicator
=
const
Center
(
child:
Text
(
'-1'
));
mockHelper
.
refreshIndicator
=
const
Center
(
child:
Text
(
'-1'
));
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
CustomScrollView
(
child:
CustomScrollView
(
slivers:
<
Widget
>[
slivers:
<
Widget
>[
CupertinoSliverRefreshControl
(
CupertinoSliverRefreshControl
(
builder:
mockHelper
.
builder
,
builder:
mockHelper
.
builder
,
...
@@ -745,9 +737,8 @@ void main() {
...
@@ -745,9 +737,8 @@ void main() {
mockHelper
.
refreshIndicator
=
const
Center
(
child:
Text
(
'-1'
));
mockHelper
.
refreshIndicator
=
const
Center
(
child:
Text
(
'-1'
));
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
CustomScrollView
(
child:
CustomScrollView
(
slivers:
<
Widget
>[
slivers:
<
Widget
>[
CupertinoSliverRefreshControl
(
CupertinoSliverRefreshControl
(
builder:
mockHelper
.
builder
,
builder:
mockHelper
.
builder
,
...
@@ -825,9 +816,8 @@ void main() {
...
@@ -825,9 +816,8 @@ void main() {
mockHelper
.
refreshIndicator
=
const
Center
(
child:
Text
(
'-1'
));
mockHelper
.
refreshIndicator
=
const
Center
(
child:
Text
(
'-1'
));
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
CustomScrollView
(
child:
CustomScrollView
(
slivers:
<
Widget
>[
slivers:
<
Widget
>[
buildAListOfStuff
(),
buildAListOfStuff
(),
CupertinoSliverRefreshControl
(
// it's in the middle now.
CupertinoSliverRefreshControl
(
// it's in the middle now.
...
@@ -852,9 +842,8 @@ void main() {
...
@@ -852,9 +842,8 @@ void main() {
mockHelper
.
refreshIndicator
=
const
Center
(
child:
Text
(
'-1'
));
mockHelper
.
refreshIndicator
=
const
Center
(
child:
Text
(
'-1'
));
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
CustomScrollView
(
child:
CustomScrollView
(
slivers:
<
Widget
>[
slivers:
<
Widget
>[
CupertinoSliverRefreshControl
(
CupertinoSliverRefreshControl
(
builder:
mockHelper
.
builder
,
builder:
mockHelper
.
builder
,
...
@@ -894,9 +883,8 @@ void main() {
...
@@ -894,9 +883,8 @@ void main() {
testWidgets
(
'Should not crash when dragged'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'Should not crash when dragged'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
CustomScrollView
(
child:
CustomScrollView
(
physics:
const
BouncingScrollPhysics
(),
physics:
const
BouncingScrollPhysics
(),
slivers:
<
Widget
>[
slivers:
<
Widget
>[
CupertinoSliverRefreshControl
(
CupertinoSliverRefreshControl
(
...
@@ -961,9 +949,8 @@ void main() {
...
@@ -961,9 +949,8 @@ void main() {
void
stateMachineTestGroup
()
{
void
stateMachineTestGroup
()
{
testWidgets
(
'starts in inactive state'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'starts in inactive state'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
CustomScrollView
(
child:
CustomScrollView
(
slivers:
<
Widget
>[
slivers:
<
Widget
>[
CupertinoSliverRefreshControl
(
CupertinoSliverRefreshControl
(
builder:
mockHelper
.
builder
,
builder:
mockHelper
.
builder
,
...
@@ -982,9 +969,8 @@ void main() {
...
@@ -982,9 +969,8 @@ void main() {
testWidgets
(
'goes to drag and returns to inactive in a small drag'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'goes to drag and returns to inactive in a small drag'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
CustomScrollView
(
child:
CustomScrollView
(
slivers:
<
Widget
>[
slivers:
<
Widget
>[
CupertinoSliverRefreshControl
(
CupertinoSliverRefreshControl
(
builder:
mockHelper
.
builder
,
builder:
mockHelper
.
builder
,
...
@@ -1013,9 +999,8 @@ void main() {
...
@@ -1013,9 +999,8 @@ void main() {
testWidgets
(
'goes to armed the frame it passes the threshold'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'goes to armed the frame it passes the threshold'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
CustomScrollView
(
child:
CustomScrollView
(
slivers:
<
Widget
>[
slivers:
<
Widget
>[
CupertinoSliverRefreshControl
(
CupertinoSliverRefreshControl
(
builder:
mockHelper
.
builder
,
builder:
mockHelper
.
builder
,
...
@@ -1047,9 +1032,8 @@ void main() {
...
@@ -1047,9 +1032,8 @@ void main() {
'goes to refresh the frame it crossed back the refresh threshold'
,
'goes to refresh the frame it crossed back the refresh threshold'
,
(
WidgetTester
tester
)
async
{
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
CustomScrollView
(
child:
CustomScrollView
(
slivers:
<
Widget
>[
slivers:
<
Widget
>[
CupertinoSliverRefreshControl
(
CupertinoSliverRefreshControl
(
builder:
mockHelper
.
builder
,
builder:
mockHelper
.
builder
,
...
@@ -1087,9 +1071,8 @@ void main() {
...
@@ -1087,9 +1071,8 @@ void main() {
'goes to done internally as soon as the task finishes'
,
'goes to done internally as soon as the task finishes'
,
(
WidgetTester
tester
)
async
{
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
CustomScrollView
(
child:
CustomScrollView
(
slivers:
<
Widget
>[
slivers:
<
Widget
>[
CupertinoSliverRefreshControl
(
CupertinoSliverRefreshControl
(
builder:
mockHelper
.
builder
,
builder:
mockHelper
.
builder
,
...
@@ -1134,9 +1117,8 @@ void main() {
...
@@ -1134,9 +1117,8 @@ void main() {
'goes back to inactive when retracting back past 10% of arming distance'
,
'goes back to inactive when retracting back past 10% of arming distance'
,
(
WidgetTester
tester
)
async
{
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
CustomScrollView
(
child:
CustomScrollView
(
slivers:
<
Widget
>[
slivers:
<
Widget
>[
CupertinoSliverRefreshControl
(
CupertinoSliverRefreshControl
(
builder:
mockHelper
.
builder
,
builder:
mockHelper
.
builder
,
...
@@ -1192,9 +1174,8 @@ void main() {
...
@@ -1192,9 +1174,8 @@ void main() {
'goes back to inactive if already scrolled away when task completes'
,
'goes back to inactive if already scrolled away when task completes'
,
(
WidgetTester
tester
)
async
{
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
CustomScrollView
(
child:
CustomScrollView
(
slivers:
<
Widget
>[
slivers:
<
Widget
>[
CupertinoSliverRefreshControl
(
CupertinoSliverRefreshControl
(
builder:
mockHelper
.
builder
,
builder:
mockHelper
.
builder
,
...
@@ -1253,9 +1234,8 @@ void main() {
...
@@ -1253,9 +1234,8 @@ void main() {
mockHelper
.
refreshIndicator
=
const
Center
(
child:
Text
(
'-1'
));
mockHelper
.
refreshIndicator
=
const
Center
(
child:
Text
(
'-1'
));
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
CustomScrollView
(
child:
CustomScrollView
(
slivers:
<
Widget
>[
slivers:
<
Widget
>[
CupertinoSliverRefreshControl
(
CupertinoSliverRefreshControl
(
builder:
null
,
builder:
null
,
...
@@ -1298,9 +1278,8 @@ void main() {
...
@@ -1298,9 +1278,8 @@ void main() {
testWidgets
(
'buildRefreshIndicator progress'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'buildRefreshIndicator progress'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
Builder
(
child:
Builder
(
builder:
(
BuildContext
context
)
{
builder:
(
BuildContext
context
)
{
return
CupertinoSliverRefreshControl
.
buildRefreshIndicator
(
return
CupertinoSliverRefreshControl
.
buildRefreshIndicator
(
context
,
context
,
...
@@ -1314,9 +1293,8 @@ void main() {
...
@@ -1314,9 +1293,8 @@ void main() {
expect
(
tester
.
widget
<
CupertinoActivityIndicator
>(
find
.
byType
(
CupertinoActivityIndicator
)).
progress
,
10.0
/
100.0
);
expect
(
tester
.
widget
<
CupertinoActivityIndicator
>(
find
.
byType
(
CupertinoActivityIndicator
)).
progress
,
10.0
/
100.0
);
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
Builder
(
child:
Builder
(
builder:
(
BuildContext
context
)
{
builder:
(
BuildContext
context
)
{
return
CupertinoSliverRefreshControl
.
buildRefreshIndicator
(
return
CupertinoSliverRefreshControl
.
buildRefreshIndicator
(
context
,
context
,
...
@@ -1330,9 +1308,8 @@ void main() {
...
@@ -1330,9 +1308,8 @@ void main() {
expect
(
tester
.
widget
<
CupertinoActivityIndicator
>(
find
.
byType
(
CupertinoActivityIndicator
)).
progress
,
26.0
/
100.0
);
expect
(
tester
.
widget
<
CupertinoActivityIndicator
>(
find
.
byType
(
CupertinoActivityIndicator
)).
progress
,
26.0
/
100.0
);
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
Builder
(
child:
Builder
(
builder:
(
BuildContext
context
)
{
builder:
(
BuildContext
context
)
{
return
CupertinoSliverRefreshControl
.
buildRefreshIndicator
(
return
CupertinoSliverRefreshControl
.
buildRefreshIndicator
(
context
,
context
,
...
@@ -1367,9 +1344,8 @@ void main() {
...
@@ -1367,9 +1344,8 @@ void main() {
(
WidgetTester
tester
)
async
{
(
WidgetTester
tester
)
async
{
// Regression test for https://github.com/flutter/flutter/issues/46871.
// Regression test for https://github.com/flutter/flutter/issues/46871.
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
CupertinoApp
(
textDirection:
TextDirection
.
ltr
,
home:
CustomScrollView
(
child:
CustomScrollView
(
physics:
const
BouncingScrollPhysics
(),
physics:
const
BouncingScrollPhysics
(),
slivers:
<
Widget
>[
slivers:
<
Widget
>[
const
CupertinoSliverRefreshControl
(),
const
CupertinoSliverRefreshControl
(),
...
...
packages/flutter/test/material/app_test.dart
View file @
e40610d6
...
@@ -1046,7 +1046,7 @@ void main() {
...
@@ -1046,7 +1046,7 @@ void main() {
late
BuildContext
capturedContext
;
late
BuildContext
capturedContext
;
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
MaterialApp
(
MaterialApp
(
scrollBehavior:
MockScrollBehavior
(),
scrollBehavior:
const
MockScrollBehavior
(),
home:
Builder
(
home:
Builder
(
builder:
(
BuildContext
context
)
{
builder:
(
BuildContext
context
)
{
capturedContext
=
context
;
capturedContext
=
context
;
...
@@ -1062,6 +1062,8 @@ void main() {
...
@@ -1062,6 +1062,8 @@ void main() {
}
}
class
MockScrollBehavior
extends
ScrollBehavior
{
class
MockScrollBehavior
extends
ScrollBehavior
{
const
MockScrollBehavior
();
@override
@override
ScrollPhysics
getScrollPhysics
(
BuildContext
context
)
=>
const
NeverScrollableScrollPhysics
();
ScrollPhysics
getScrollPhysics
(
BuildContext
context
)
=>
const
NeverScrollableScrollPhysics
();
}
}
...
...
packages/flutter/test/material/scrollbar_test.dart
View file @
e40610d6
...
@@ -49,11 +49,21 @@ Widget _buildBoilerplate({
...
@@ -49,11 +49,21 @@ Widget _buildBoilerplate({
textDirection:
textDirection
,
textDirection:
textDirection
,
child:
MediaQuery
(
child:
MediaQuery
(
data:
MediaQueryData
(
padding:
padding
),
data:
MediaQueryData
(
padding:
padding
),
child:
ScrollConfiguration
(
behavior:
const
NoScrollbarBehavior
(),
child:
child
,
child:
child
,
),
),
),
);
);
}
}
class
NoScrollbarBehavior
extends
MaterialScrollBehavior
{
const
NoScrollbarBehavior
();
@override
Widget
buildScrollbar
(
BuildContext
context
,
Widget
child
,
ScrollableDetails
details
)
=>
child
;
}
void
main
(
)
{
void
main
(
)
{
testWidgets
(
"Scrollbar doesn't show when tapping list"
,
(
WidgetTester
tester
)
async
{
testWidgets
(
"Scrollbar doesn't show when tapping list"
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
...
@@ -809,20 +819,13 @@ void main() {
...
@@ -809,20 +819,13 @@ void main() {
});
});
testWidgets
(
'Scrollbar thumb color completes a hover animation'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'Scrollbar thumb color completes a hover animation'
,
(
WidgetTester
tester
)
async
{
final
ScrollController
scrollController
=
ScrollController
();
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
MaterialApp
(
MaterialApp
(
home:
PrimaryScrollController
(
theme:
ThemeData
(
scrollbarTheme:
const
ScrollbarThemeData
(
isAlwaysShown:
true
)),
controller:
scrollController
,
home:
const
SingleChildScrollView
(
child:
Scrollbar
(
isAlwaysShown:
true
,
controller:
scrollController
,
child:
const
SingleChildScrollView
(
child:
SizedBox
(
width:
4000.0
,
height:
4000.0
)
child:
SizedBox
(
width:
4000.0
,
height:
4000.0
)
),
),
),
),
),
),
);
);
await
tester
.
pumpAndSettle
();
await
tester
.
pumpAndSettle
();
expect
(
expect
(
...
@@ -858,26 +861,20 @@ void main() {
...
@@ -858,26 +861,20 @@ void main() {
TargetPlatform
.
linux
,
TargetPlatform
.
linux
,
TargetPlatform
.
macOS
,
TargetPlatform
.
macOS
,
TargetPlatform
.
windows
,
TargetPlatform
.
windows
,
TargetPlatform
.
fuchsia
,
}),
}),
);
);
testWidgets
(
'Hover animation is not triggered by tap gestures'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'Hover animation is not triggered by tap gestures'
,
(
WidgetTester
tester
)
async
{
final
ScrollController
scrollController
=
ScrollController
();
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
MaterialApp
(
MaterialApp
(
home:
PrimaryScrollController
(
theme:
ThemeData
(
scrollbarTheme:
const
ScrollbarThemeData
(
controller:
scrollController
,
child:
Scrollbar
(
isAlwaysShown:
true
,
isAlwaysShown:
true
,
showTrackOnHover:
true
,
showTrackOnHover:
true
,
controller:
scrollController
,
))
,
child
:
const
SingleChildScrollView
(
home
:
const
SingleChildScrollView
(
child:
SizedBox
(
width:
4000.0
,
height:
4000.0
)
child:
SizedBox
(
width:
4000.0
,
height:
4000.0
)
),
),
),
),
),
),
);
);
await
tester
.
pumpAndSettle
();
await
tester
.
pumpAndSettle
();
expect
(
expect
(
...
@@ -936,29 +933,21 @@ void main() {
...
@@ -936,29 +933,21 @@ void main() {
color:
const
Color
(
0x80000000
),
color:
const
Color
(
0x80000000
),
),
),
);
);
},
},
variant:
const
TargetPlatformVariant
(<
TargetPlatform
>{
variant:
const
TargetPlatformVariant
(<
TargetPlatform
>{
TargetPlatform
.
linux
}),
TargetPlatform
.
linux
,
}),
);
);
testWidgets
(
'Scrollbar showTrackOnHover'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'Scrollbar showTrackOnHover'
,
(
WidgetTester
tester
)
async
{
final
ScrollController
scrollController
=
ScrollController
();
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
MaterialApp
(
MaterialApp
(
home:
PrimaryScrollController
(
theme:
ThemeData
(
scrollbarTheme:
const
ScrollbarThemeData
(
controller:
scrollController
,
child:
Scrollbar
(
isAlwaysShown:
true
,
isAlwaysShown:
true
,
showTrackOnHover:
true
,
showTrackOnHover:
true
,
controller:
scrollController
,
))
,
child
:
const
SingleChildScrollView
(
home
:
const
SingleChildScrollView
(
child:
SizedBox
(
width:
4000.0
,
height:
4000.0
)
child:
SizedBox
(
width:
4000.0
,
height:
4000.0
)
),
),
),
),
),
),
);
);
await
tester
.
pumpAndSettle
();
await
tester
.
pumpAndSettle
();
expect
(
expect
(
...
@@ -1006,7 +995,6 @@ void main() {
...
@@ -1006,7 +995,6 @@ void main() {
TargetPlatform
.
linux
,
TargetPlatform
.
linux
,
TargetPlatform
.
macOS
,
TargetPlatform
.
macOS
,
TargetPlatform
.
windows
,
TargetPlatform
.
windows
,
TargetPlatform
.
fuchsia
,
}),
}),
);
);
...
@@ -1088,6 +1076,8 @@ void main() {
...
@@ -1088,6 +1076,8 @@ void main() {
textDirection:
TextDirection
.
ltr
,
textDirection:
TextDirection
.
ltr
,
child:
MediaQuery
(
child:
MediaQuery
(
data:
const
MediaQueryData
(),
data:
const
MediaQueryData
(),
child:
ScrollConfiguration
(
behavior:
const
NoScrollbarBehavior
(),
child:
Scrollbar
(
child:
Scrollbar
(
key:
key2
,
key:
key2
,
notificationPredicate:
null
,
notificationPredicate:
null
,
...
@@ -1121,6 +1111,7 @@ void main() {
...
@@ -1121,6 +1111,7 @@ void main() {
),
),
),
),
),
),
),
);
);
// Drag the inner scrollable widget.
// Drag the inner scrollable widget.
...
@@ -1206,11 +1197,7 @@ void main() {
...
@@ -1206,11 +1197,7 @@ void main() {
await
tester
.
pumpAndSettle
();
await
tester
.
pumpAndSettle
();
// The offset should not have changed.
// The offset should not have changed.
expect
(
scrollController
.
offset
,
scrollAmount
);
expect
(
scrollController
.
offset
,
scrollAmount
);
},
variant:
const
TargetPlatformVariant
(<
TargetPlatform
>{
},
variant:
const
TargetPlatformVariant
(<
TargetPlatform
>{
TargetPlatform
.
fuchsia
}));
TargetPlatform
.
linux
,
TargetPlatform
.
windows
,
TargetPlatform
.
fuchsia
,
}));
testWidgets
(
'Scrollbar dragging is disabled by default on Android'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'Scrollbar dragging is disabled by default on Android'
,
(
WidgetTester
tester
)
async
{
final
ScrollController
scrollController
=
ScrollController
();
final
ScrollController
scrollController
=
ScrollController
();
...
...
packages/flutter/test/material/scrollbar_theme_test.dart
View file @
e40610d6
...
@@ -29,7 +29,9 @@ void main() {
...
@@ -29,7 +29,9 @@ void main() {
final
ScrollController
scrollController
=
ScrollController
();
final
ScrollController
scrollController
=
ScrollController
();
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
MaterialApp
(
MaterialApp
(
home:
Scrollbar
(
home:
ScrollConfiguration
(
behavior:
const
NoScrollbarBehavior
(),
child:
Scrollbar
(
isAlwaysShown:
true
,
isAlwaysShown:
true
,
showTrackOnHover:
true
,
showTrackOnHover:
true
,
controller:
scrollController
,
controller:
scrollController
,
...
@@ -39,6 +41,7 @@ void main() {
...
@@ -39,6 +41,7 @@ void main() {
),
),
),
),
),
),
),
);
);
await
tester
.
pumpAndSettle
();
await
tester
.
pumpAndSettle
();
// Idle scrollbar behavior
// Idle scrollbar behavior
...
@@ -117,8 +120,12 @@ void main() {
...
@@ -117,8 +120,12 @@ void main() {
final
ScrollbarThemeData
scrollbarTheme
=
_scrollbarTheme
();
final
ScrollbarThemeData
scrollbarTheme
=
_scrollbarTheme
();
final
ScrollController
scrollController
=
ScrollController
();
final
ScrollController
scrollController
=
ScrollController
();
await
tester
.
pumpWidget
(
MaterialApp
(
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
ThemeData
(
scrollbarTheme:
scrollbarTheme
),
theme:
ThemeData
(
home:
Scrollbar
(
scrollbarTheme:
scrollbarTheme
,
),
home:
ScrollConfiguration
(
behavior:
const
NoScrollbarBehavior
(),
child:
Scrollbar
(
isAlwaysShown:
true
,
isAlwaysShown:
true
,
controller:
scrollController
,
controller:
scrollController
,
child:
SingleChildScrollView
(
child:
SingleChildScrollView
(
...
@@ -126,6 +133,7 @@ void main() {
...
@@ -126,6 +133,7 @@ void main() {
child:
const
SizedBox
(
width:
4000.0
,
height:
4000.0
)
child:
const
SizedBox
(
width:
4000.0
,
height:
4000.0
)
),
),
),
),
),
));
));
await
tester
.
pumpAndSettle
();
await
tester
.
pumpAndSettle
();
// Idle scrollbar behavior
// Idle scrollbar behavior
...
@@ -245,12 +253,7 @@ void main() {
...
@@ -245,12 +253,7 @@ void main() {
color:
_kDefaultIdleThumbColor
,
color:
_kDefaultIdleThumbColor
,
),
),
);
);
},
variant:
const
TargetPlatformVariant
(<
TargetPlatform
>{
},
variant:
const
TargetPlatformVariant
(<
TargetPlatform
>{
TargetPlatform
.
fuchsia
}));
TargetPlatform
.
linux
,
TargetPlatform
.
macOS
,
TargetPlatform
.
windows
,
TargetPlatform
.
fuchsia
,
}));
testWidgets
(
'Scrollbar.interactive takes priority over ScrollbarTheme'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'Scrollbar.interactive takes priority over ScrollbarTheme'
,
(
WidgetTester
tester
)
async
{
final
ScrollController
scrollController
=
ScrollController
();
final
ScrollController
scrollController
=
ScrollController
();
...
@@ -298,12 +301,7 @@ void main() {
...
@@ -298,12 +301,7 @@ void main() {
color:
_kDefaultIdleThumbColor
,
color:
_kDefaultIdleThumbColor
,
),
),
);
);
},
variant:
const
TargetPlatformVariant
(<
TargetPlatform
>{
},
variant:
const
TargetPlatformVariant
(<
TargetPlatform
>{
TargetPlatform
.
fuchsia
}));
TargetPlatform
.
linux
,
TargetPlatform
.
macOS
,
TargetPlatform
.
windows
,
TargetPlatform
.
fuchsia
,
}));
testWidgets
(
'Scrollbar widget properties take priority over theme'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'Scrollbar widget properties take priority over theme'
,
(
WidgetTester
tester
)
async
{
const
double
thickness
=
4.0
;
const
double
thickness
=
4.0
;
...
@@ -314,8 +312,12 @@ void main() {
...
@@ -314,8 +312,12 @@ void main() {
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
MaterialApp
(
MaterialApp
(
theme:
ThemeData
.
from
(
colorScheme:
const
ColorScheme
.
light
()),
theme:
ThemeData
(
home:
Scrollbar
(
colorScheme:
const
ColorScheme
.
light
(),
),
home:
ScrollConfiguration
(
behavior:
const
NoScrollbarBehavior
(),
child:
Scrollbar
(
thickness:
thickness
,
thickness:
thickness
,
hoverThickness:
hoverThickness
,
hoverThickness:
hoverThickness
,
isAlwaysShown:
true
,
isAlwaysShown:
true
,
...
@@ -328,6 +330,7 @@ void main() {
...
@@ -328,6 +330,7 @@ void main() {
),
),
),
),
),
),
),
);
);
await
tester
.
pumpAndSettle
();
await
tester
.
pumpAndSettle
();
...
@@ -408,7 +411,9 @@ void main() {
...
@@ -408,7 +411,9 @@ void main() {
final
ScrollController
scrollController
=
ScrollController
();
final
ScrollController
scrollController
=
ScrollController
();
return
MaterialApp
(
return
MaterialApp
(
theme:
appTheme
,
theme:
appTheme
,
home:
Scrollbar
(
home:
ScrollConfiguration
(
behavior:
const
NoScrollbarBehavior
(),
child:
Scrollbar
(
isAlwaysShown:
true
,
isAlwaysShown:
true
,
showTrackOnHover:
true
,
showTrackOnHover:
true
,
controller:
scrollController
,
controller:
scrollController
,
...
@@ -416,13 +421,16 @@ void main() {
...
@@ -416,13 +421,16 @@ void main() {
controller:
scrollController
,
controller:
scrollController
,
child:
const
SizedBox
(
width:
4000.0
,
height:
4000.0
)
child:
const
SizedBox
(
width:
4000.0
,
height:
4000.0
)
),
),
),
)
)
);
);
}
}
// Scrollbar defaults for light themes:
// Scrollbar defaults for light themes:
// - coloring based on ColorScheme.onSurface
// - coloring based on ColorScheme.onSurface
await
tester
.
pumpWidget
(
buildFrame
(
ThemeData
.
from
(
colorScheme:
const
ColorScheme
.
light
())));
await
tester
.
pumpWidget
(
buildFrame
(
ThemeData
(
colorScheme:
const
ColorScheme
.
light
(),
)));
await
tester
.
pumpAndSettle
();
await
tester
.
pumpAndSettle
();
// Idle scrollbar behavior
// Idle scrollbar behavior
expect
(
expect
(
...
@@ -493,7 +501,9 @@ void main() {
...
@@ -493,7 +501,9 @@ void main() {
// Scrollbar defaults for dark themes:
// Scrollbar defaults for dark themes:
// - coloring slightly different based on ColorScheme.onSurface
// - coloring slightly different based on ColorScheme.onSurface
await
tester
.
pumpWidget
(
buildFrame
(
ThemeData
.
from
(
colorScheme:
const
ColorScheme
.
dark
())));
await
tester
.
pumpWidget
(
buildFrame
(
ThemeData
(
colorScheme:
const
ColorScheme
.
dark
(),
)));
await
tester
.
pumpAndSettle
();
// Theme change animation
await
tester
.
pumpAndSettle
();
// Theme change animation
// Idle scrollbar behavior
// Idle scrollbar behavior
...
@@ -617,6 +627,13 @@ void main() {
...
@@ -617,6 +627,13 @@ void main() {
},
skip:
kIsWeb
);
},
skip:
kIsWeb
);
}
}
class
NoScrollbarBehavior
extends
ScrollBehavior
{
const
NoScrollbarBehavior
();
@override
Widget
buildScrollbar
(
BuildContext
context
,
Widget
child
,
ScrollableDetails
details
)
=>
child
;
}
ScrollbarThemeData
_scrollbarTheme
(
{
ScrollbarThemeData
_scrollbarTheme
(
{
MaterialStateProperty
<
double
?>?
thickness
,
MaterialStateProperty
<
double
?>?
thickness
,
bool
showTrackOnHover
=
true
,
bool
showTrackOnHover
=
true
,
...
...
packages/flutter/test/rendering/viewport_test.dart
View file @
e40610d6
...
@@ -1788,6 +1788,8 @@ void main() {
...
@@ -1788,6 +1788,8 @@ void main() {
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
Directionality
(
textDirection:
TextDirection
.
ltr
,
textDirection:
TextDirection
.
ltr
,
child:
MediaQuery
(
data:
const
MediaQueryData
(),
child:
Column
(
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
crossAxisAlignment:
CrossAxisAlignment
.
start
,
mainAxisAlignment:
MainAxisAlignment
.
center
,
mainAxisAlignment:
MainAxisAlignment
.
center
,
...
@@ -1808,6 +1810,7 @@ void main() {
...
@@ -1808,6 +1810,7 @@ void main() {
],
],
),
),
),
),
),
);
);
expect
(
find
.
text
(
'b'
),
findsOneWidget
);
expect
(
find
.
text
(
'b'
),
findsOneWidget
);
...
...
packages/flutter/test/widgets/app_test.dart
View file @
e40610d6
...
@@ -327,11 +327,6 @@ void main() {
...
@@ -327,11 +327,6 @@ void main() {
});
});
}
}
class
MockScrollBehavior
extends
ScrollBehavior
{
@override
ScrollPhysics
getScrollPhysics
(
BuildContext
context
)
=>
const
NeverScrollableScrollPhysics
();
}
typedef
SimpleRouterDelegateBuilder
=
Widget
Function
(
BuildContext
,
RouteInformation
);
typedef
SimpleRouterDelegateBuilder
=
Widget
Function
(
BuildContext
,
RouteInformation
);
typedef
SimpleNavigatorRouterDelegatePopPage
<
T
>
=
bool
Function
(
Route
<
T
>
route
,
T
result
,
SimpleNavigatorRouterDelegate
delegate
);
typedef
SimpleNavigatorRouterDelegatePopPage
<
T
>
=
bool
Function
(
Route
<
T
>
route
,
T
result
,
SimpleNavigatorRouterDelegate
delegate
);
...
...
packages/flutter/test/widgets/draggable_scrollable_sheet_test.dart
View file @
e40610d6
...
@@ -18,6 +18,8 @@ void main() {
...
@@ -18,6 +18,8 @@ void main() {
})
{
})
{
return
Directionality
(
return
Directionality
(
textDirection:
TextDirection
.
ltr
,
textDirection:
TextDirection
.
ltr
,
child:
MediaQuery
(
data:
const
MediaQueryData
(),
child:
Stack
(
child:
Stack
(
children:
<
Widget
>[
children:
<
Widget
>[
TextButton
(
TextButton
(
...
@@ -46,6 +48,7 @@ void main() {
...
@@ -46,6 +48,7 @@ void main() {
),
),
],
],
),
),
),
);
);
}
}
...
...
packages/flutter/test/widgets/overscroll_indicator_test.dart
View file @
e40610d6
...
@@ -278,11 +278,11 @@ void main() {
...
@@ -278,11 +278,11 @@ void main() {
RenderObject
painter
;
RenderObject
painter
;
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
const
Directionality
(
textDirection:
TextDirection
.
ltr
,
textDirection:
TextDirection
.
ltr
,
child:
ScrollConfiguration
(
child:
ScrollConfiguration
(
behavior:
TestScrollBehavior1
(),
behavior:
TestScrollBehavior1
(),
child:
const
CustomScrollView
(
child:
CustomScrollView
(
scrollDirection:
Axis
.
horizontal
,
scrollDirection:
Axis
.
horizontal
,
physics:
AlwaysScrollableScrollPhysics
(),
physics:
AlwaysScrollableScrollPhysics
(),
reverse:
true
,
reverse:
true
,
...
@@ -300,11 +300,11 @@ void main() {
...
@@ -300,11 +300,11 @@ void main() {
await
tester
.
pumpAndSettle
(
const
Duration
(
seconds:
1
));
await
tester
.
pumpAndSettle
(
const
Duration
(
seconds:
1
));
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
Directionality
(
const
Directionality
(
textDirection:
TextDirection
.
ltr
,
textDirection:
TextDirection
.
ltr
,
child:
ScrollConfiguration
(
child:
ScrollConfiguration
(
behavior:
TestScrollBehavior2
(),
behavior:
TestScrollBehavior2
(),
child:
const
CustomScrollView
(
child:
CustomScrollView
(
scrollDirection:
Axis
.
horizontal
,
scrollDirection:
Axis
.
horizontal
,
physics:
AlwaysScrollableScrollPhysics
(),
physics:
AlwaysScrollableScrollPhysics
(),
slivers:
<
Widget
>[
slivers:
<
Widget
>[
...
@@ -326,7 +326,7 @@ void main() {
...
@@ -326,7 +326,7 @@ void main() {
Directionality
(
Directionality
(
textDirection:
TextDirection
.
ltr
,
textDirection:
TextDirection
.
ltr
,
child:
ScrollConfiguration
(
child:
ScrollConfiguration
(
behavior:
TestScrollBehavior2
(),
behavior:
const
TestScrollBehavior2
(),
child:
CustomScrollView
(
child:
CustomScrollView
(
center:
centerKey
,
center:
centerKey
,
physics:
const
AlwaysScrollableScrollPhysics
(),
physics:
const
AlwaysScrollableScrollPhysics
(),
...
@@ -365,7 +365,7 @@ void main() {
...
@@ -365,7 +365,7 @@ void main() {
Directionality
(
Directionality
(
textDirection:
TextDirection
.
ltr
,
textDirection:
TextDirection
.
ltr
,
child:
ScrollConfiguration
(
child:
ScrollConfiguration
(
behavior:
TestScrollBehavior2
(),
behavior:
const
TestScrollBehavior2
(),
child:
NotificationListener
<
OverscrollIndicatorNotification
>(
child:
NotificationListener
<
OverscrollIndicatorNotification
>(
onNotification:
(
OverscrollIndicatorNotification
notification
)
{
onNotification:
(
OverscrollIndicatorNotification
notification
)
{
if
(
notification
.
leading
)
{
if
(
notification
.
leading
)
{
...
@@ -534,22 +534,26 @@ void main() {
...
@@ -534,22 +534,26 @@ void main() {
}
}
class
TestScrollBehavior1
extends
ScrollBehavior
{
class
TestScrollBehavior1
extends
ScrollBehavior
{
const
TestScrollBehavior1
();
@override
@override
Widget
build
ViewportChrome
(
BuildContext
context
,
Widget
child
,
AxisDirection
axisDirection
)
{
Widget
build
OverscrollIndicator
(
BuildContext
context
,
Widget
child
,
ScrollableDetails
details
)
{
return
GlowingOverscrollIndicator
(
return
GlowingOverscrollIndicator
(
child:
child
,
child:
child
,
axisDirection:
axisD
irection
,
axisDirection:
details
.
d
irection
,
color:
const
Color
(
0xFF00FF00
),
color:
const
Color
(
0xFF00FF00
),
);
);
}
}
}
}
class
TestScrollBehavior2
extends
ScrollBehavior
{
class
TestScrollBehavior2
extends
ScrollBehavior
{
const
TestScrollBehavior2
();
@override
@override
Widget
build
ViewportChrome
(
BuildContext
context
,
Widget
child
,
AxisDirection
axisDirection
)
{
Widget
build
OverscrollIndicator
(
BuildContext
context
,
Widget
child
,
ScrollableDetails
details
)
{
return
GlowingOverscrollIndicator
(
return
GlowingOverscrollIndicator
(
child:
child
,
child:
child
,
axisDirection:
axisD
irection
,
axisDirection:
details
.
d
irection
,
color:
const
Color
(
0xFF0000FF
),
color:
const
Color
(
0xFF0000FF
),
);
);
}
}
...
...
packages/flutter/test/widgets/range_maintaining_scroll_physics_test.dart
View file @
e40610d6
...
@@ -304,7 +304,12 @@ class RangeMaintainingTestScrollBehavior extends ScrollBehavior {
...
@@ -304,7 +304,12 @@ class RangeMaintainingTestScrollBehavior extends ScrollBehavior {
TargetPlatform
getPlatform
(
BuildContext
context
)
=>
throw
'should not be called'
;
TargetPlatform
getPlatform
(
BuildContext
context
)
=>
throw
'should not be called'
;
@override
@override
Widget
buildViewportChrome
(
BuildContext
context
,
Widget
child
,
AxisDirection
axisDirection
)
{
Widget
buildOverscrollIndicator
(
BuildContext
context
,
Widget
child
,
ScrollableDetails
details
)
{
return
child
;
}
@override
Widget
buildScrollbar
(
BuildContext
context
,
Widget
child
,
ScrollableDetails
details
)
{
return
child
;
return
child
;
}
}
...
...
packages/flutter/test/widgets/scrollable_test.dart
View file @
e40610d6
...
@@ -19,6 +19,7 @@ Future<void> pumpTest(
...
@@ -19,6 +19,7 @@ Future<void> pumpTest(
ScrollController
?
controller
,
ScrollController
?
controller
,
})
async
{
})
async
{
await
tester
.
pumpWidget
(
MaterialApp
(
await
tester
.
pumpWidget
(
MaterialApp
(
scrollBehavior:
const
NoScrollbarBehavior
(),
theme:
ThemeData
(
theme:
ThemeData
(
platform:
platform
,
platform:
platform
,
),
),
...
@@ -34,6 +35,13 @@ Future<void> pumpTest(
...
@@ -34,6 +35,13 @@ Future<void> pumpTest(
await
tester
.
pump
(
const
Duration
(
seconds:
5
));
// to let the theme animate
await
tester
.
pump
(
const
Duration
(
seconds:
5
));
// to let the theme animate
}
}
class
NoScrollbarBehavior
extends
MaterialScrollBehavior
{
const
NoScrollbarBehavior
();
@override
Widget
buildScrollbar
(
BuildContext
context
,
Widget
child
,
ScrollableDetails
details
)
=>
child
;
}
// Pump a nested scrollable. The outer scrollable contains a sliver of a
// Pump a nested scrollable. The outer scrollable contains a sliver of a
// 300-pixel-long scrollable followed by a 2000-pixel-long content.
// 300-pixel-long scrollable followed by a 2000-pixel-long content.
Future
<
void
>
pumpDoubleScrollableTest
(
Future
<
void
>
pumpDoubleScrollableTest
(
...
...
packages/flutter/test/widgets/slivers_evil_test.dart
View file @
e40610d6
...
@@ -32,11 +32,13 @@ class TestSliverPersistentHeaderDelegate extends SliverPersistentHeaderDelegate
...
@@ -32,11 +32,13 @@ class TestSliverPersistentHeaderDelegate extends SliverPersistentHeaderDelegate
}
}
class
TestBehavior
extends
ScrollBehavior
{
class
TestBehavior
extends
ScrollBehavior
{
const
TestBehavior
();
@override
@override
Widget
build
ViewportChrome
(
BuildContext
context
,
Widget
child
,
AxisDirection
axisDirection
)
{
Widget
build
OverscrollIndicator
(
BuildContext
context
,
Widget
child
,
ScrollableDetails
details
)
{
return
GlowingOverscrollIndicator
(
return
GlowingOverscrollIndicator
(
child:
child
,
child:
child
,
axisDirection:
axisD
irection
,
axisDirection:
details
.
d
irection
,
color:
const
Color
(
0xFFFFFFFF
),
color:
const
Color
(
0xFFFFFFFF
),
);
);
}
}
...
@@ -78,7 +80,7 @@ void main() {
...
@@ -78,7 +80,7 @@ void main() {
child:
Directionality
(
child:
Directionality
(
textDirection:
TextDirection
.
ltr
,
textDirection:
TextDirection
.
ltr
,
child:
ScrollConfiguration
(
child:
ScrollConfiguration
(
behavior:
TestBehavior
(),
behavior:
const
TestBehavior
(),
child:
Scrollbar
(
child:
Scrollbar
(
child:
Scrollable
(
child:
Scrollable
(
axisDirection:
AxisDirection
.
down
,
axisDirection:
AxisDirection
.
down
,
...
...
packages/flutter/test/widgets/state_setting_in_scrollables_test.dart
View file @
e40610d6
...
@@ -19,7 +19,7 @@ class FooState extends State<Foo> {
...
@@ -19,7 +19,7 @@ class FooState extends State<Foo> {
return
LayoutBuilder
(
return
LayoutBuilder
(
builder:
(
BuildContext
context
,
BoxConstraints
constraints
)
{
builder:
(
BuildContext
context
,
BoxConstraints
constraints
)
{
return
ScrollConfiguration
(
return
ScrollConfiguration
(
behavior:
FooScrollBehavior
(),
behavior:
const
FooScrollBehavior
(),
child:
ListView
(
child:
ListView
(
controller:
scrollController
,
controller:
scrollController
,
children:
<
Widget
>[
children:
<
Widget
>[
...
@@ -74,6 +74,8 @@ class FooState extends State<Foo> {
...
@@ -74,6 +74,8 @@ class FooState extends State<Foo> {
}
}
class
FooScrollBehavior
extends
ScrollBehavior
{
class
FooScrollBehavior
extends
ScrollBehavior
{
const
FooScrollBehavior
();
@override
@override
bool
shouldNotify
(
FooScrollBehavior
old
)
=>
true
;
bool
shouldNotify
(
FooScrollBehavior
old
)
=>
true
;
}
}
...
...
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