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
2d3d2209
Unverified
Commit
2d3d2209
authored
Nov 26, 2019
by
Dan Field
Committed by
GitHub
Nov 26, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implicit scrolling for pageview (#45598)
parent
7d8f8205
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
104 additions
and
6 deletions
+104
-6
page_view.dart
packages/flutter/lib/src/widgets/page_view.dart
+61
-5
scroll_physics.dart
packages/flutter/lib/src/widgets/scroll_physics.dart
+1
-1
page_view_test.dart
packages/flutter/test/widgets/page_view_test.dart
+42
-0
No files found.
packages/flutter/lib/src/widgets/page_view.dart
View file @
2d3d2209
...
...
@@ -416,6 +416,25 @@ class _PagePosition extends ScrollPositionWithSingleContext implements PageMetri
}
}
class
_ForceImplicitScrollPhysics
extends
ScrollPhysics
{
const
_ForceImplicitScrollPhysics
({
@required
this
.
allowImplicitScrolling
,
ScrollPhysics
parent
,
})
:
assert
(
allowImplicitScrolling
!=
null
),
super
(
parent:
parent
);
@override
_ForceImplicitScrollPhysics
applyTo
(
ScrollPhysics
ancestor
)
{
return
_ForceImplicitScrollPhysics
(
allowImplicitScrolling:
allowImplicitScrolling
,
parent:
buildParent
(
ancestor
),
);
}
@override
final
bool
allowImplicitScrolling
;
}
/// Scroll physics used by a [PageView].
///
/// These physics cause the page view to snap to page boundaries.
...
...
@@ -512,6 +531,13 @@ class PageView extends StatefulWidget {
/// children because constructing the [List] requires doing work for every
/// child that could possibly be displayed in the page view, instead of just
/// those children that are actually visible.
///
/// {@template flutter.widgets.pageView.allowImplicitScrolling}
/// The [allowImplicitScrolling] parameter must not be null. If true, the
/// [PageView] will participate in accessibility scrolling more like a
/// [ListView], where implicit scroll actions will move to the next page
/// rather than into the contents of the [PageView].
/// {@endtemplate}
PageView
({
Key
key
,
this
.
scrollDirection
=
Axis
.
horizontal
,
...
...
@@ -522,7 +548,9 @@ class PageView extends StatefulWidget {
this
.
onPageChanged
,
List
<
Widget
>
children
=
const
<
Widget
>[],
this
.
dragStartBehavior
=
DragStartBehavior
.
start
,
})
:
controller
=
controller
??
_defaultPageController
,
this
.
allowImplicitScrolling
=
false
,
})
:
assert
(
allowImplicitScrolling
!=
null
),
controller
=
controller
??
_defaultPageController
,
childrenDelegate
=
SliverChildListDelegate
(
children
),
super
(
key:
key
);
...
...
@@ -542,6 +570,8 @@ class PageView extends StatefulWidget {
/// [PageView.builder] by default does not support child reordering. If
/// you are planning to change child order at a later time, consider using
/// [PageView] or [PageView.custom].
///
/// {@macro flutter.widgets.pageView.allowImplicitScrolling}
PageView
.
builder
({
Key
key
,
this
.
scrollDirection
=
Axis
.
horizontal
,
...
...
@@ -553,7 +583,9 @@ class PageView extends StatefulWidget {
@required
IndexedWidgetBuilder
itemBuilder
,
int
itemCount
,
this
.
dragStartBehavior
=
DragStartBehavior
.
start
,
})
:
controller
=
controller
??
_defaultPageController
,
this
.
allowImplicitScrolling
=
false
,
})
:
assert
(
allowImplicitScrolling
!=
null
),
controller
=
controller
??
_defaultPageController
,
childrenDelegate
=
SliverChildBuilderDelegate
(
itemBuilder
,
childCount:
itemCount
),
super
(
key:
key
);
...
...
@@ -637,6 +669,8 @@ class PageView extends StatefulWidget {
/// }
/// ```
/// {@end-tool}
///
/// {@macro flutter.widgets.pageView.allowImplicitScrolling}
PageView
.
custom
({
Key
key
,
this
.
scrollDirection
=
Axis
.
horizontal
,
...
...
@@ -647,10 +681,25 @@ class PageView extends StatefulWidget {
this
.
onPageChanged
,
@required
this
.
childrenDelegate
,
this
.
dragStartBehavior
=
DragStartBehavior
.
start
,
this
.
allowImplicitScrolling
=
false
,
})
:
assert
(
childrenDelegate
!=
null
),
assert
(
allowImplicitScrolling
!=
null
),
controller
=
controller
??
_defaultPageController
,
super
(
key:
key
);
/// Controls whether the widget's pages will respond to
/// [RenderObject.showOnScreen], which will allow for implicit accessibility
/// scrolling.
///
/// With this flag set to false, when accessibility focus reaches the end of
/// the current page and the user attempts to move it to the next element, the
/// focus will traverse to the next widget outside of the page view.
///
/// With this flag set to true, when accessibility focus reaches the end of
/// the current page and user attempts to move it to the next element, focus
/// will traverse to the next page in the page view.
final
bool
allowImplicitScrolling
;
/// The axis along which the page view scrolls.
///
/// Defaults to [Axis.horizontal].
...
...
@@ -731,9 +780,11 @@ class _PageViewState extends State<PageView> {
@override
Widget
build
(
BuildContext
context
)
{
final
AxisDirection
axisDirection
=
_getDirection
(
context
);
final
ScrollPhysics
physics
=
widget
.
pageSnapping
final
ScrollPhysics
physics
=
_ForceImplicitScrollPhysics
(
allowImplicitScrolling:
widget
.
allowImplicitScrolling
,
).
applyTo
(
widget
.
pageSnapping
?
_kPagePhysics
.
applyTo
(
widget
.
physics
)
:
widget
.
physics
;
:
widget
.
physics
)
;
return
NotificationListener
<
ScrollNotification
>(
onNotification:
(
ScrollNotification
notification
)
{
...
...
@@ -754,7 +805,11 @@ class _PageViewState extends State<PageView> {
physics:
physics
,
viewportBuilder:
(
BuildContext
context
,
ViewportOffset
position
)
{
return
Viewport
(
cacheExtent:
0.0
,
// TODO(dnfield): we should provide a way to set cacheExtent
// independent of implicit scrolling:
// https://github.com/flutter/flutter/issues/45632
cacheExtent:
widget
.
allowImplicitScrolling
?
1.0
:
0.0
,
cacheExtentStyle:
CacheExtentStyle
.
viewport
,
axisDirection:
axisDirection
,
offset:
position
,
slivers:
<
Widget
>[
...
...
@@ -777,5 +832,6 @@ class _PageViewState extends State<PageView> {
description
.
add
(
DiagnosticsProperty
<
PageController
>(
'controller'
,
widget
.
controller
,
showName:
false
));
description
.
add
(
DiagnosticsProperty
<
ScrollPhysics
>(
'physics'
,
widget
.
physics
,
showName:
false
));
description
.
add
(
FlagProperty
(
'pageSnapping'
,
value:
widget
.
pageSnapping
,
ifFalse:
'snapping disabled'
));
description
.
add
(
FlagProperty
(
'allowImplicitScrolling'
,
value:
widget
.
allowImplicitScrolling
,
ifTrue:
'allow implicit scrolling'
));
}
}
packages/flutter/lib/src/widgets/scroll_physics.dart
View file @
2d3d2209
...
...
@@ -259,7 +259,7 @@ class ScrollPhysics {
double
get
dragStartDistanceMotionThreshold
=>
parent
?.
dragStartDistanceMotionThreshold
;
/// Whether a viewport is allowed to change its scroll position implicitly in
/// respon
ds
to a call to [RenderObject.showOnScreen].
/// respon
se
to a call to [RenderObject.showOnScreen].
///
/// [RenderObject.showOnScreen] is for example used to bring a text field
/// fully on screen after it has received focus. This property controls
...
...
packages/flutter/test/widgets/page_view_test.dart
View file @
2d3d2209
...
...
@@ -784,4 +784,46 @@ void main() {
pageController
.
position
.
jumpTo
(
799.99999999999
);
expect
(
pageController
.
page
,
1
);
});
testWidgets
(
'PageView can participate in a11y scrolling'
,
(
WidgetTester
tester
)
async
{
final
SemanticsTester
semantics
=
SemanticsTester
(
tester
);
final
PageController
controller
=
PageController
();
await
tester
.
pumpWidget
(
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
PageView
(
controller:
controller
,
children:
List
<
Widget
>.
generate
(
4
,
(
int
i
)
{
return
Semantics
(
child:
Text
(
'Page #
$i
'
),
container:
true
,
);
}),
allowImplicitScrolling:
true
,
),
));
expect
(
controller
.
page
,
0
);
expect
(
semantics
,
includesNodeWith
(
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
hasImplicitScrolling
]));
expect
(
semantics
,
includesNodeWith
(
label:
'Page #0'
));
expect
(
semantics
,
includesNodeWith
(
label:
'Page #1'
,
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
]));
expect
(
semantics
,
isNot
(
includesNodeWith
(
label:
'Page #2'
,
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
])));
expect
(
semantics
,
isNot
(
includesNodeWith
(
label:
'Page #3'
,
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
])));
controller
.
nextPage
(
duration:
const
Duration
(
milliseconds:
150
),
curve:
Curves
.
ease
);
await
tester
.
pumpAndSettle
();
expect
(
semantics
,
includesNodeWith
(
label:
'Page #0'
,
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
]));
expect
(
semantics
,
includesNodeWith
(
label:
'Page #1'
));
expect
(
semantics
,
includesNodeWith
(
label:
'Page #2'
,
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
]));
expect
(
semantics
,
isNot
(
includesNodeWith
(
label:
'Page #3'
,
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
])));
controller
.
nextPage
(
duration:
const
Duration
(
milliseconds:
150
),
curve:
Curves
.
ease
);
await
tester
.
pumpAndSettle
();
expect
(
semantics
,
isNot
(
includesNodeWith
(
label:
'Page #0'
,
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
])));
expect
(
semantics
,
includesNodeWith
(
label:
'Page #1'
,
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
]));
expect
(
semantics
,
includesNodeWith
(
label:
'Page #2'
));
expect
(
semantics
,
includesNodeWith
(
label:
'Page #3'
,
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isHidden
]));
semantics
.
dispose
();
});
}
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