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
3681aee5
Commit
3681aee5
authored
May 05, 2017
by
Hans Muller
Committed by
GitHub
May 05, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Selectively enable page scrolling in the gallery animation demo (#9845)
parent
6337a055
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
224 additions
and
60 deletions
+224
-60
home.dart
examples/flutter_gallery/lib/demo/animation/home.dart
+70
-48
page_view.dart
packages/flutter/lib/src/widgets/page_view.dart
+3
-1
scroll_physics.dart
packages/flutter/lib/src/widgets/scroll_physics.dart
+60
-8
scrollable.dart
packages/flutter/lib/src/widgets/scrollable.dart
+10
-2
scroll_physics_test.dart
packages/flutter/test/widgets/scroll_physics_test.dart
+78
-0
slivers_evil_test.dart
packages/flutter/test/widgets/slivers_evil_test.dart
+3
-1
No files found.
examples/flutter_gallery/lib/demo/animation/home.dart
View file @
3681aee5
...
...
@@ -313,7 +313,7 @@ class _AllSectionsView extends AnimatedWidget {
(
midHeight
-
minHeight
)).
clamp
(
0.0
,
1.0
);
double
_indicatorOpacity
(
int
index
)
{
return
1.0
-
_selectedIndexDelta
(
index
)
*
tColumnToRow
*
0.5
;
return
1.0
-
_selectedIndexDelta
(
index
)
*
0.5
;
}
double
_titleOpacity
(
int
index
)
{
...
...
@@ -369,16 +369,15 @@ class _AllSectionsView extends AnimatedWidget {
// app bar's height is _kAppBarMidHeight and only one section heading is
// visible.
class
_SnappingScrollPhysics
extends
ClampingScrollPhysics
{
_SnappingScrollPhysics
({
ScrollPhysics
parent
,
this
.
midScrollOffset
})
:
super
(
parent:
parent
);
_SnappingScrollPhysics
({
ScrollPhysics
parent
,
this
.
midScrollOffset
})
:
super
(
parent:
parent
)
{
assert
(
midScrollOffset
!=
null
);
}
final
double
midScrollOffset
;
@override
_SnappingScrollPhysics
applyTo
(
ScrollPhysics
parent
)
{
return
new
_SnappingScrollPhysics
(
parent:
parent
,
midScrollOffset:
midScrollOffset
);
_SnappingScrollPhysics
applyTo
(
ScrollPhysics
ancestor
)
{
return
new
_SnappingScrollPhysics
(
parent:
buildParent
(
ancestor
),
midScrollOffset:
midScrollOffset
);
}
Simulation
_toMidScrollOffsetSimulation
(
double
offset
,
double
dragVelocity
)
{
...
...
@@ -436,6 +435,7 @@ class _AnimationDemoHomeState extends State<AnimationDemoHome> {
final
ScrollController
_scrollController
=
new
ScrollController
();
final
PageController
_headingPageController
=
new
PageController
();
final
PageController
_detailsPageController
=
new
PageController
();
ScrollPhysics
_headingScrollPhysics
=
const
NeverScrollableScrollPhysics
();
ValueNotifier
<
double
>
selectedIndex
=
new
ValueNotifier
<
double
>(
0.0
);
@override
...
...
@@ -449,6 +449,22 @@ class _AnimationDemoHomeState extends State<AnimationDemoHome> {
);
}
// Only enable paging for the heading when the user has scrolled to midScrollOffset.
// Paging is enabled/disabled by setting the heading's PageView scroll physics.
bool
_handleScrollNotification
(
ScrollNotification
notification
,
double
midScrollOffset
)
{
if
(
notification
.
depth
==
0
&&
notification
is
ScrollUpdateNotification
)
{
final
ScrollPhysics
physics
=
_scrollController
.
position
.
pixels
>=
midScrollOffset
?
const
PageScrollPhysics
()
:
const
NeverScrollableScrollPhysics
();
if
(
physics
!=
_headingScrollPhysics
)
{
setState
(()
{
_headingScrollPhysics
=
physics
;
});
}
}
return
false
;
}
void
_maybeScroll
(
double
midScrollOffset
,
int
pageIndex
,
double
xOffset
)
{
const
Duration
duration
=
const
Duration
(
milliseconds:
400
);
const
Curve
curve
=
Curves
.
fastOutSlowIn
;
...
...
@@ -532,53 +548,59 @@ class _AnimationDemoHomeState extends State<AnimationDemoHome> {
return
new
SizedBox
.
expand
(
child:
new
Stack
(
children:
<
Widget
>[
new
CustomScrollView
(
controller:
_scrollController
,
physics:
new
_SnappingScrollPhysics
(
midScrollOffset:
appBarMidScrollOffset
),
slivers:
<
Widget
>[
// Start out below the status bar, gradually move to the top of the screen.
new
_StatusBarPaddingSliver
(
maxHeight:
statusBarHeight
,
scrollFactor:
7.0
,
),
// Section Headings
new
SliverPersistentHeader
(
pinned:
true
,
delegate:
new
_SliverAppBarDelegate
(
minHeight:
_kAppBarMinHeight
,
maxHeight:
appBarMaxHeight
,
child:
new
NotificationListener
<
ScrollNotification
>(
onNotification:
(
ScrollNotification
notification
)
{
return
_handlePageNotification
(
notification
,
_headingPageController
,
_detailsPageController
);
},
child:
new
PageView
(
controller:
_headingPageController
,
children:
_allHeadingItems
(
appBarMaxHeight
,
appBarMidScrollOffset
),
new
NotificationListener
<
ScrollNotification
>(
onNotification:
(
ScrollNotification
notification
)
{
return
_handleScrollNotification
(
notification
,
appBarMidScrollOffset
);
},
child:
new
CustomScrollView
(
controller:
_scrollController
,
physics:
new
_SnappingScrollPhysics
(
midScrollOffset:
appBarMidScrollOffset
),
slivers:
<
Widget
>[
// Start out below the status bar, gradually move to the top of the screen.
new
_StatusBarPaddingSliver
(
maxHeight:
statusBarHeight
,
scrollFactor:
7.0
,
),
// Section Headings
new
SliverPersistentHeader
(
pinned:
true
,
delegate:
new
_SliverAppBarDelegate
(
minHeight:
_kAppBarMinHeight
,
maxHeight:
appBarMaxHeight
,
child:
new
NotificationListener
<
ScrollNotification
>(
onNotification:
(
ScrollNotification
notification
)
{
return
_handlePageNotification
(
notification
,
_headingPageController
,
_detailsPageController
);
},
child:
new
PageView
(
physics:
_headingScrollPhysics
,
controller:
_headingPageController
,
children:
_allHeadingItems
(
appBarMaxHeight
,
appBarMidScrollOffset
),
),
),
),
),
),
// Details
new
SliverToBoxAdapter
(
child:
new
SizedBox
(
height:
610.0
,
child:
new
NotificationListener
<
ScrollNotification
>(
onNotification:
(
ScrollNotification
notification
)
{
return
_handlePageNotification
(
notification
,
_detailsPageController
,
_headingPageController
);
},
child:
new
PageView
(
controller:
_detailsPageController
,
children:
allSections
.
map
((
Section
section
)
{
return
new
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
children:
_detailItemsFor
(
section
).
toList
(),
);
}).
toList
(
),
// Details
new
SliverToBoxAdapter
(
child:
new
SizedBox
(
height:
610.0
,
child:
new
NotificationListener
<
ScrollNotification
>(
onNotification:
(
ScrollNotification
notification
)
{
return
_handlePageNotification
(
notification
,
_detailsPageController
,
_headingPageController
);
},
child:
new
PageView
(
controller:
_detailsPageController
,
children:
allSections
.
map
((
Section
section
)
{
return
new
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
children:
_detailItemsFor
(
section
).
toList
()
,
);
}).
toList
(),
),
),
),
),
)
,
]
,
]
,
)
,
),
new
Positioned
(
top:
statusBarHeight
,
...
...
packages/flutter/lib/src/widgets/page_view.dart
View file @
3681aee5
...
...
@@ -233,7 +233,9 @@ class PageScrollPhysics extends ScrollPhysics {
const
PageScrollPhysics
({
ScrollPhysics
parent
})
:
super
(
parent:
parent
);
@override
PageScrollPhysics
applyTo
(
ScrollPhysics
parent
)
=>
new
PageScrollPhysics
(
parent:
parent
);
PageScrollPhysics
applyTo
(
ScrollPhysics
ancestor
)
{
return
new
PageScrollPhysics
(
parent:
buildParent
(
ancestor
));
}
double
_getPage
(
ScrollPosition
position
)
{
if
(
position
is
_PagePosition
)
...
...
packages/flutter/lib/src/widgets/scroll_physics.dart
View file @
3681aee5
...
...
@@ -37,13 +37,35 @@ class ScrollPhysics {
/// [ScrollPhysics] subclasses at runtime.
final
ScrollPhysics
parent
;
/// Return a [ScrollPhysics] with the same [runtimeType] where the [parent]
/// has been replaced with the given [parent].
/// If [parent] is null then return ancestor, otherwise recursively build a
/// ScrollPhysics that has [ancestor] as its parent.
///
/// This method is typically used to define [applyTo] methods like:
/// ```dart
/// FooScrollPhysics applyTo(ScrollPhysics ancestor) {
/// return new FooScrollPhysics(parent: buildParent(ancestor));
/// }
/// ```
@protected
ScrollPhysics
buildParent
(
ScrollPhysics
ancestor
)
=>
parent
?.
applyTo
(
ancestor
)
??
ancestor
;
/// If [parent] is null then return a [ScrollPhysics] with the same
/// [runtimeType] where the [parent] has been replaced with the [ancestor].
///
/// If this scroll physics object already has a parent, then this method
/// is applied recursively and ancestor will appear at the end of the
/// existing chain of parents.
///
/// The returned object will combine some of the behaviors from this
/// [ScrollPhysics] instance and some of the behaviors from the given
/// [ScrollPhysics] instance.
ScrollPhysics
applyTo
(
ScrollPhysics
parent
)
=>
new
ScrollPhysics
(
parent:
parent
);
/// [ScrollPhysics] instance and some of the behaviors from [ancestor].
///
/// See also:
///
/// * [buildParent], a utility method that's often used to define [applyTo]
/// methods for ScrollPhysics subclasses.
ScrollPhysics
applyTo
(
ScrollPhysics
ancestor
)
{
return
new
ScrollPhysics
(
parent:
buildParent
(
ancestor
));
}
/// Used by [DragScrollActivity] and other user-driven activities to
/// convert an offset in logical pixels as provided by the [DragUpdateDetails]
...
...
@@ -198,7 +220,9 @@ class BouncingScrollPhysics extends ScrollPhysics {
const
BouncingScrollPhysics
({
ScrollPhysics
parent
})
:
super
(
parent:
parent
);
@override
BouncingScrollPhysics
applyTo
(
ScrollPhysics
parent
)
=>
new
BouncingScrollPhysics
(
parent:
parent
);
BouncingScrollPhysics
applyTo
(
ScrollPhysics
ancestor
)
{
return
new
BouncingScrollPhysics
(
parent:
buildParent
(
ancestor
));
}
/// The multiple applied to overscroll to make it appear that scrolling past
/// the edge of the scrollable contents is harder than scrolling the list.
...
...
@@ -277,7 +301,9 @@ class ClampingScrollPhysics extends ScrollPhysics {
const
ClampingScrollPhysics
({
ScrollPhysics
parent
})
:
super
(
parent:
parent
);
@override
ClampingScrollPhysics
applyTo
(
ScrollPhysics
parent
)
=>
new
ClampingScrollPhysics
(
parent:
parent
);
ClampingScrollPhysics
applyTo
(
ScrollPhysics
ancestor
)
{
return
new
ClampingScrollPhysics
(
parent:
buildParent
(
ancestor
));
}
@override
double
applyBoundaryConditions
(
ScrollMetrics
position
,
double
value
)
{
...
...
@@ -359,8 +385,34 @@ class AlwaysScrollableScrollPhysics extends ScrollPhysics {
const
AlwaysScrollableScrollPhysics
({
ScrollPhysics
parent
})
:
super
(
parent:
parent
);
@override
AlwaysScrollableScrollPhysics
applyTo
(
ScrollPhysics
parent
)
=>
new
AlwaysScrollableScrollPhysics
(
parent:
parent
);
AlwaysScrollableScrollPhysics
applyTo
(
ScrollPhysics
ancestor
)
{
return
new
AlwaysScrollableScrollPhysics
(
parent:
buildParent
(
ancestor
));
}
@override
bool
shouldAcceptUserOffset
(
ScrollMetrics
position
)
=>
true
;
}
/// Scroll physics that does not allow the user to scroll.
///
/// See also:
///
/// * [ScrollPhysics], which can be used instead of this class when the default
/// behavior is desired instead.
/// * [BouncingScrollPhysics], which provides the bouncing overscroll behavior
/// found on iOS.
/// * [ClampingScrollPhysics], which provides the clamping overscroll behavior
/// found on Android.
class
NeverScrollableScrollPhysics
extends
ScrollPhysics
{
/// Creates scroll physics that does not let the user scroll.
const
NeverScrollableScrollPhysics
({
ScrollPhysics
parent
})
:
super
(
parent:
parent
);
@override
NeverScrollableScrollPhysics
applyTo
(
ScrollPhysics
ancestor
)
{
return
new
NeverScrollableScrollPhysics
(
parent:
buildParent
(
ancestor
));
}
@override
bool
shouldAcceptUserOffset
(
ScrollMetrics
position
)
=>
false
;
}
packages/flutter/lib/src/widgets/scrollable.dart
View file @
3681aee5
...
...
@@ -271,8 +271,16 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin
}
bool
_shouldUpdatePosition
(
Scrollable
oldWidget
)
{
return
widget
.
physics
?.
runtimeType
!=
oldWidget
.
physics
?.
runtimeType
||
widget
.
controller
?.
runtimeType
!=
oldWidget
.
controller
?.
runtimeType
;
ScrollPhysics
newPhysics
=
widget
.
physics
;
ScrollPhysics
oldPhysics
=
oldWidget
.
physics
;
do
{
if
(
newPhysics
?.
runtimeType
!=
oldPhysics
?.
runtimeType
)
return
true
;
newPhysics
=
newPhysics
?.
parent
;
oldPhysics
=
oldPhysics
?.
parent
;
}
while
(
newPhysics
!=
null
||
oldPhysics
!=
null
);
return
widget
.
controller
?.
runtimeType
!=
oldWidget
.
controller
?.
runtimeType
;
}
@override
...
...
packages/flutter/test/widgets/scroll_physics_test.dart
0 → 100644
View file @
3681aee5
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/widgets.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
class
TestScrollPhysics
extends
ScrollPhysics
{
const
TestScrollPhysics
({
this
.
name
,
ScrollPhysics
parent
})
:
super
(
parent:
parent
);
final
String
name
;
@override
TestScrollPhysics
applyTo
(
ScrollPhysics
ancestor
)
{
return
new
TestScrollPhysics
(
name:
name
,
parent:
parent
?.
applyTo
(
ancestor
)
??
ancestor
);
}
TestScrollPhysics
get
namedParent
=>
parent
;
String
get
names
=>
parent
==
null
?
name
:
'
$name
${namedParent.names}
'
;
@override
String
toString
()
{
if
(
parent
==
null
)
return
'
$runtimeType
(
$name
)'
;
return
'
$runtimeType
(
$name
) ->
$parent
'
;
}
}
void
main
(
)
{
test
(
'ScrollPhysics applyTo()'
,
()
{
const
ScrollPhysics
a
=
const
TestScrollPhysics
(
name:
'a'
);
const
ScrollPhysics
b
=
const
TestScrollPhysics
(
name:
'b'
);
const
ScrollPhysics
c
=
const
TestScrollPhysics
(
name:
'c'
);
const
ScrollPhysics
d
=
const
TestScrollPhysics
(
name:
'd'
);
const
ScrollPhysics
e
=
const
TestScrollPhysics
(
name:
'e'
);
expect
(
a
.
parent
,
null
);
expect
(
b
.
parent
,
null
);
expect
(
c
.
parent
,
null
);
final
TestScrollPhysics
ab
=
a
.
applyTo
(
b
);
expect
(
ab
.
names
,
'a b'
);
final
TestScrollPhysics
abc
=
ab
.
applyTo
(
c
);
expect
(
abc
.
names
,
'a b c'
);
final
TestScrollPhysics
de
=
d
.
applyTo
(
e
);
expect
(
de
.
names
,
'd e'
);
final
TestScrollPhysics
abcde
=
abc
.
applyTo
(
de
);
expect
(
abcde
.
names
,
'a b c d e'
);
});
test
(
'ScrollPhysics subclasses applyTo()'
,
()
{
const
ScrollPhysics
bounce
=
const
BouncingScrollPhysics
();
const
ScrollPhysics
clamp
=
const
ClampingScrollPhysics
();
const
ScrollPhysics
never
=
const
NeverScrollableScrollPhysics
();
const
ScrollPhysics
always
=
const
AlwaysScrollableScrollPhysics
();
const
ScrollPhysics
page
=
const
PageScrollPhysics
();
String
types
(
ScrollPhysics
s
)
=>
s
.
parent
==
null
?
'
${s.runtimeType}
'
:
'
${s.runtimeType}
${types(s.parent)}
'
;
expect
(
types
(
bounce
.
applyTo
(
clamp
.
applyTo
(
never
.
applyTo
(
always
.
applyTo
(
page
))))),
'BouncingScrollPhysics ClampingScrollPhysics NeverScrollableScrollPhysics AlwaysScrollableScrollPhysics PageScrollPhysics'
);
expect
(
types
(
clamp
.
applyTo
(
never
.
applyTo
(
always
.
applyTo
(
page
.
applyTo
(
bounce
))))),
'ClampingScrollPhysics NeverScrollableScrollPhysics AlwaysScrollableScrollPhysics PageScrollPhysics BouncingScrollPhysics'
);
expect
(
types
(
never
.
applyTo
(
always
.
applyTo
(
page
.
applyTo
(
bounce
.
applyTo
(
clamp
))))),
'NeverScrollableScrollPhysics AlwaysScrollableScrollPhysics PageScrollPhysics BouncingScrollPhysics ClampingScrollPhysics'
);
expect
(
types
(
always
.
applyTo
(
page
.
applyTo
(
bounce
.
applyTo
(
clamp
.
applyTo
(
never
))))),
'AlwaysScrollableScrollPhysics PageScrollPhysics BouncingScrollPhysics ClampingScrollPhysics NeverScrollableScrollPhysics'
);
expect
(
types
(
page
.
applyTo
(
bounce
.
applyTo
(
clamp
.
applyTo
(
never
.
applyTo
(
always
))))),
'PageScrollPhysics BouncingScrollPhysics ClampingScrollPhysics NeverScrollableScrollPhysics AlwaysScrollableScrollPhysics'
);
});
}
packages/flutter/test/widgets/slivers_evil_test.dart
View file @
3681aee5
...
...
@@ -47,7 +47,9 @@ class TestScrollPhysics extends ClampingScrollPhysics {
const
TestScrollPhysics
({
ScrollPhysics
parent
})
:
super
(
parent:
parent
);
@override
TestScrollPhysics
applyTo
(
ScrollPhysics
parent
)
=>
new
TestScrollPhysics
(
parent:
parent
);
TestScrollPhysics
applyTo
(
ScrollPhysics
ancestor
)
{
return
new
TestScrollPhysics
(
parent:
parent
?.
applyTo
(
ancestor
)
??
ancestor
);
}
@override
Tolerance
get
tolerance
=>
const
Tolerance
(
velocity:
20.0
,
distance:
1.0
);
...
...
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