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
dac80aac
Commit
dac80aac
authored
Mar 21, 2017
by
Hans Muller
Committed by
GitHub
Mar 21, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make min/max fling velocity and min fling distance ScrollPhysics properties (#8928)
parent
14933de9
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
284 additions
and
209 deletions
+284
-209
drag.dart
packages/flutter/lib/src/gestures/drag.dart
+62
-27
velocity_tracker.dart
packages/flutter/lib/src/gestures/velocity_tracker.dart
+158
-159
scroll_physics.dart
packages/flutter/lib/src/widgets/scroll_physics.dart
+22
-15
scroll_position.dart
packages/flutter/lib/src/widgets/scroll_position.dart
+27
-0
scrollable.dart
packages/flutter/lib/src/widgets/scrollable.dart
+14
-7
modal_bottom_sheet_test.dart
packages/flutter/test/material/modal_bottom_sheet_test.dart
+1
-1
No files found.
packages/flutter/lib/src/gestures/drag.dart
View file @
dac80aac
...
...
@@ -20,10 +20,10 @@ enum _DragState {
///
/// See also:
///
/// * [DragGestureRecognizer.onDown], which uses [GestureDragDownCallback].
/// * [DragStartDetails], the details for [GestureDragStartCallback].
/// * [DragUpdateDetails], the details for [GestureDragUpdateCallback].
/// * [DragEndDetails], the details for [GestureDragEndCallback].
///
* [DragGestureRecognizer.onDown], which uses [GestureDragDownCallback].
///
* [DragStartDetails], the details for [GestureDragStartCallback].
///
* [DragUpdateDetails], the details for [GestureDragUpdateCallback].
///
* [DragEndDetails], the details for [GestureDragEndCallback].
class
DragDownDetails
{
/// Creates details for a [GestureDragDownCallback].
///
...
...
@@ -53,10 +53,10 @@ typedef void GestureDragDownCallback(DragDownDetails details);
///
/// See also:
///
/// * [DragGestureRecognizer.onStart], which uses [GestureDragStartCallback].
/// * [DragDownDetails], the details for [GestureDragDownCallback].
/// * [DragUpdateDetails], the details for [GestureDragUpdateCallback].
/// * [DragEndDetails], the details for [GestureDragEndCallback].
///
* [DragGestureRecognizer.onStart], which uses [GestureDragStartCallback].
///
* [DragDownDetails], the details for [GestureDragDownCallback].
///
* [DragUpdateDetails], the details for [GestureDragUpdateCallback].
///
* [DragEndDetails], the details for [GestureDragEndCallback].
class
DragStartDetails
{
/// Creates details for a [GestureDragStartCallback].
///
...
...
@@ -86,10 +86,10 @@ typedef void GestureDragStartCallback(DragStartDetails details);
///
/// See also:
///
/// * [DragGestureRecognizer.onUpdate], which uses [GestureDragUpdateCallback].
/// * [DragDownDetails], the details for [GestureDragDownCallback].
/// * [DragStartDetails], the details for [GestureDragStartCallback].
/// * [DragEndDetails], the details for [GestureDragEndCallback].
///
* [DragGestureRecognizer.onUpdate], which uses [GestureDragUpdateCallback].
///
* [DragDownDetails], the details for [GestureDragDownCallback].
///
* [DragStartDetails], the details for [GestureDragStartCallback].
///
* [DragEndDetails], the details for [GestureDragEndCallback].
class
DragUpdateDetails
{
/// Creates details for a [DragUpdateDetails].
///
...
...
@@ -150,10 +150,10 @@ typedef void GestureDragUpdateCallback(DragUpdateDetails details);
///
/// See also:
///
/// * [DragGestureRecognizer.onEnd], which uses [GestureDragEndCallback].
/// * [DragDownDetails], the details for [GestureDragDownCallback].
/// * [DragStartDetails], the details for [GestureDragStartCallback].
/// * [DragUpdateDetails], the details for [GestureDragUpdateCallback].
///
* [DragGestureRecognizer.onEnd], which uses [GestureDragEndCallback].
///
* [DragDownDetails], the details for [GestureDragDownCallback].
///
* [DragStartDetails], the details for [GestureDragStartCallback].
///
* [DragUpdateDetails], the details for [GestureDragUpdateCallback].
class
DragEndDetails
{
/// Creates details for a [GestureDragEndCallback].
///
...
...
@@ -204,12 +204,6 @@ typedef void GestureDragEndCallback(DragEndDetails details);
/// See [DragGestureRecognizer.onCancel].
typedef
void
GestureDragCancelCallback
(
);
bool
_isFlingGesture
(
Velocity
velocity
)
{
assert
(
velocity
!=
null
);
final
double
speedSquared
=
velocity
.
pixelsPerSecond
.
distanceSquared
;
return
speedSquared
>
kMinFlingVelocity
*
kMinFlingVelocity
;
}
/// Recognizes movement.
///
/// In contrast to [MultiDragGestureRecognizer], [DragGestureRecognizer]
...
...
@@ -256,10 +250,30 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
/// The pointer that previously triggered [onDown] did not complete.
GestureDragCancelCallback
onCancel
;
/// The minimum distance an input pointer drag must have moved to
/// to be considered a fling gesture.
///
/// This value is typically compared with the distance traveled along the
/// scrolling axis. If null then [kTouchSlop] is used.
double
minFlingDistance
;
/// The minimum velocity for an input pointer drag to be considered fling.
///
/// This value is typically compared with the magnitude of fling gesture's
/// velocity along the scrolling axis. If null then [kMinFlingVelocity]
/// is used.
double
minFlingVelocity
;
/// Fling velocity magnitudes will be clamped to this value.
///
/// If null then [kMaxFlingVelocity] is used.
double
maxFlingVelocity
;
_DragState
_state
=
_DragState
.
ready
;
Point
_initialPosition
;
Offset
_pendingDragOffset
;
bool
_isFlingGesture
(
VelocityEstimate
estimate
);
Offset
_getDeltaForDetails
(
Offset
delta
);
double
_getPrimaryValueFromOffset
(
Offset
value
);
bool
get
_hasSufficientPendingDragDeltaToAccept
;
...
...
@@ -345,11 +359,10 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
final
VelocityTracker
tracker
=
_velocityTrackers
[
pointer
];
assert
(
tracker
!=
null
);
Velocity
velocity
=
tracker
.
getVelocity
();
if
(
velocity
!=
null
&&
_isFlingGesture
(
velocity
))
{
final
Offset
pixelsPerSecond
=
velocity
.
pixelsPerSecond
;
if
(
pixelsPerSecond
.
distanceSquared
>
kMaxFlingVelocity
*
kMaxFlingVelocity
)
velocity
=
new
Velocity
(
pixelsPerSecond:
(
pixelsPerSecond
/
pixelsPerSecond
.
distance
)
*
kMaxFlingVelocity
);
final
VelocityEstimate
estimate
=
tracker
.
getVelocityEstimate
();
if
(
estimate
!=
null
&&
_isFlingGesture
(
estimate
))
{
final
Velocity
velocity
=
new
Velocity
(
pixelsPerSecond:
estimate
.
pixelsPerSecond
)
.
clampMagnitude
(
minFlingVelocity
??
kMinFlingVelocity
,
maxFlingVelocity
??
kMaxFlingVelocity
);
invokeCallback
<
Null
>(
'onEnd'
,
()
=>
onEnd
(
new
DragEndDetails
(
// ignore: STRONG_MODE_INVALID_CAST_FUNCTION_EXPR, https://github.com/dart-lang/sdk/issues/27504
velocity:
velocity
,
primaryVelocity:
_getPrimaryValueFromOffset
(
velocity
.
pixelsPerSecond
),
...
...
@@ -379,6 +392,13 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
///
/// * [VerticalMultiDragGestureRecognizer]
class
VerticalDragGestureRecognizer
extends
DragGestureRecognizer
{
@override
bool
_isFlingGesture
(
VelocityEstimate
estimate
)
{
final
double
minVelocity
=
minFlingVelocity
??
kMinFlingVelocity
;
final
double
minDistance
=
minFlingDistance
??
kTouchSlop
;
return
estimate
.
pixelsPerSecond
.
dy
.
abs
()
>
minVelocity
&&
estimate
.
offset
.
dy
.
abs
()
>
minDistance
;
}
@override
bool
get
_hasSufficientPendingDragDeltaToAccept
=>
_pendingDragOffset
.
dy
.
abs
()
>
kTouchSlop
;
...
...
@@ -400,6 +420,13 @@ class VerticalDragGestureRecognizer extends DragGestureRecognizer {
///
/// * [HorizontalMultiDragGestureRecognizer]
class
HorizontalDragGestureRecognizer
extends
DragGestureRecognizer
{
@override
bool
_isFlingGesture
(
VelocityEstimate
estimate
)
{
final
double
minVelocity
=
minFlingVelocity
??
kMinFlingVelocity
;
final
double
minDistance
=
minFlingDistance
??
kTouchSlop
;
return
estimate
.
pixelsPerSecond
.
dx
.
abs
()
>
minVelocity
&&
estimate
.
offset
.
dx
.
abs
()
>
minDistance
;
}
@override
bool
get
_hasSufficientPendingDragDeltaToAccept
=>
_pendingDragOffset
.
dx
.
abs
()
>
kTouchSlop
;
...
...
@@ -420,6 +447,14 @@ class HorizontalDragGestureRecognizer extends DragGestureRecognizer {
/// * [ImmediateMultiDragGestureRecognizer]
/// * [DelayedMultiDragGestureRecognizer]
class
PanGestureRecognizer
extends
DragGestureRecognizer
{
@override
bool
_isFlingGesture
(
VelocityEstimate
estimate
)
{
final
double
minVelocity
=
minFlingVelocity
??
kMinFlingVelocity
;
final
double
minDistance
=
minFlingDistance
??
kTouchSlop
;
return
estimate
.
pixelsPerSecond
.
distanceSquared
>
minVelocity
*
minVelocity
&&
estimate
.
offset
.
distanceSquared
>
minDistance
*
minDistance
;
}
@override
bool
get
_hasSufficientPendingDragDeltaToAccept
{
return
_pendingDragOffset
.
distance
>
kPanSlop
;
...
...
packages/flutter/lib/src/gestures/velocity_tracker.dart
View file @
dac80aac
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/widgets/scroll_physics.dart
View file @
dac80aac
...
...
@@ -4,6 +4,7 @@
import
'dart:math'
as
math
;
import
'package:flutter/gestures.dart'
show
kMinFlingVelocity
;
import
'package:flutter/physics.dart'
;
import
'overscroll_indicator.dart'
;
...
...
@@ -22,10 +23,10 @@ export 'scroll_position.dart' show ScrollPhysics;
///
/// See also:
///
/// * [ViewportScrollBehavior], which uses this to provide the iOS component of
/// its scroll behavior.
/// * [ClampingScrollPhysics], which is the analogous physics for Android's
/// clamping behavior.
///
* [ViewportScrollBehavior], which uses this to provide the iOS component of
///
its scroll behavior.
///
* [ClampingScrollPhysics], which is the analogous physics for Android's
///
clamping behavior.
class
BouncingScrollPhysics
extends
ScrollPhysics
{
/// Creates scroll physics that bounce back from the edge.
const
BouncingScrollPhysics
({
ScrollPhysics
parent
})
:
super
(
parent
);
...
...
@@ -81,6 +82,12 @@ class BouncingScrollPhysics extends ScrollPhysics {
}
return
null
;
}
// The ballistic simulation here decelerates more slowly than the one for
// ClampingScrollPhysics so we require a more deliberate input gesture
// to trigger a fling.
@override
double
get
minFlingVelocity
=>
kMinFlingVelocity
*
2.0
;
}
/// Scroll physics for environments that prevent the scroll offset from reaching
...
...
@@ -90,13 +97,13 @@ class BouncingScrollPhysics extends ScrollPhysics {
///
/// See also:
///
/// * [ViewportScrollBehavior], which uses this to provide the Android component
/// of its scroll behavior.
/// * [BouncingScrollPhysics], which is the analogous physics for iOS' bouncing
/// behavior.
/// * [GlowingOverscrollIndicator], which is used by [ViewportScrollBehavior] to
/// provide the glowing effect that is usually found with this clamping effect
/// on Android.
///
* [ViewportScrollBehavior], which uses this to provide the Android component
///
of its scroll behavior.
///
* [BouncingScrollPhysics], which is the analogous physics for iOS' bouncing
///
behavior.
///
* [GlowingOverscrollIndicator], which is used by [ViewportScrollBehavior] to
///
provide the glowing effect that is usually found with this clamping effect
///
on Android.
class
ClampingScrollPhysics
extends
ScrollPhysics
{
/// Creates scroll physics that prevent the scroll offset from exceeding the
/// bounds of the content..
...
...
@@ -156,10 +163,10 @@ class ClampingScrollPhysics extends ScrollPhysics {
///
/// See also:
///
/// * [BouncingScrollPhysics], which provides the bouncing overscroll behavior
/// found on iOS.
/// * [ClampingScrollPhysics], which provides the clamping overscroll behavior
/// found on Android.
///
* [BouncingScrollPhysics], which provides the bouncing overscroll behavior
///
found on iOS.
///
* [ClampingScrollPhysics], which provides the clamping overscroll behavior
///
found on Android.
class
AlwaysScrollableScrollPhysics
extends
ScrollPhysics
{
/// Creates scroll physics that always lets the user scroll.
const
AlwaysScrollableScrollPhysics
({
ScrollPhysics
parent
})
:
super
(
parent
);
...
...
packages/flutter/lib/src/widgets/scroll_position.dart
View file @
dac80aac
...
...
@@ -106,6 +106,33 @@ abstract class ScrollPhysics {
Tolerance
get
tolerance
=>
parent
?.
tolerance
??
_kDefaultTolerance
;
/// The minimum distance an input pointer drag must have moved to
/// to be considered a scroll fling gesture.
///
/// This value is typically compared with the distance traveled along the
/// scrolling axis.
///
/// See also:
///
/// * [VelocityTracker.getVelocityEstimate], which computes the velocity
/// of a press-drag-release gesture.
double
get
minFlingDistance
=>
parent
?.
minFlingDistance
??
kTouchSlop
;
/// The minimum velocity for an input pointer drag to be considered a
/// scroll fling.
///
/// This value is typically compared with the magnitude of fling gesture's
/// velocity along the scrolling axis.
///
/// See also:
///
/// * [VelocityTracker.getVelocityEstimate], which computes the velocity
/// of a press-drag-release gesture.
double
get
minFlingVelocity
=>
parent
?.
minFlingVelocity
??
kMinFlingVelocity
;
/// Scroll fling velocity magnitudes will be clamped to this value.
double
get
maxFlingVelocity
=>
parent
?.
maxFlingVelocity
??
kMaxFlingVelocity
;
@override
String
toString
()
{
if
(
parent
==
null
)
...
...
packages/flutter/lib/src/widgets/scrollable.dart
View file @
dac80aac
...
...
@@ -118,13 +118,14 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin
ScrollPosition
_position
;
ScrollBehavior
_configuration
;
ScrollPhysics
_physics
;
//
only call this from places that will definitely trigger a rebuild
//
Only call this from places that will definitely trigger a rebuild.
void
_updatePosition
()
{
_configuration
=
ScrollConfiguration
.
of
(
context
);
ScrollPhysics
physics
=
_configuration
.
getScrollPhysics
(
context
);
_
physics
=
_configuration
.
getScrollPhysics
(
context
);
if
(
config
.
physics
!=
null
)
physics
=
config
.
physics
.
applyTo
(
physics
);
_physics
=
config
.
physics
.
applyTo
(
_
physics
);
final
ScrollController
controller
=
config
.
controller
;
final
ScrollPosition
oldPosition
=
position
;
if
(
oldPosition
!=
null
)
{
...
...
@@ -135,8 +136,8 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin
scheduleMicrotask
(
oldPosition
.
dispose
);
}
_position
=
controller
?.
createScrollPosition
(
physics
,
this
,
oldPosition
)
??
ScrollController
.
createDefaultScrollPosition
(
physics
,
this
,
oldPosition
);
_position
=
controller
?.
createScrollPosition
(
_
physics
,
this
,
oldPosition
)
??
ScrollController
.
createDefaultScrollPosition
(
_
physics
,
this
,
oldPosition
);
assert
(
position
!=
null
);
controller
?.
attach
(
position
);
}
...
...
@@ -201,7 +202,10 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin
..
onDown
=
_handleDragDown
..
onStart
=
_handleDragStart
..
onUpdate
=
_handleDragUpdate
..
onEnd
=
_handleDragEnd
;
..
onEnd
=
_handleDragEnd
..
minFlingDistance
=
_physics
?.
minFlingDistance
..
minFlingVelocity
=
_physics
?.
minFlingVelocity
..
maxFlingVelocity
=
_physics
?.
maxFlingVelocity
;
}
};
break
;
...
...
@@ -212,7 +216,10 @@ class ScrollableState extends State<Scrollable> with TickerProviderStateMixin
..
onDown
=
_handleDragDown
..
onStart
=
_handleDragStart
..
onUpdate
=
_handleDragUpdate
..
onEnd
=
_handleDragEnd
;
..
onEnd
=
_handleDragEnd
..
minFlingDistance
=
_physics
?.
minFlingDistance
..
minFlingVelocity
=
_physics
?.
minFlingVelocity
..
maxFlingVelocity
=
_physics
?.
maxFlingVelocity
;
}
};
break
;
...
...
packages/flutter/test/material/modal_bottom_sheet_test.dart
View file @
dac80aac
...
...
@@ -102,7 +102,7 @@ void main() {
expect
(
showBottomSheetThenCalled
,
isFalse
);
expect
(
find
.
text
(
'BottomSheet'
),
findsOneWidget
);
await
tester
.
fling
(
find
.
text
(
'BottomSheet'
),
const
Offset
(
0.0
,
2
0.0
),
1000.0
);
await
tester
.
fling
(
find
.
text
(
'BottomSheet'
),
const
Offset
(
0.0
,
3
0.0
),
1000.0
);
await
tester
.
pump
();
// drain the microtask queue (Future completion callback)
expect
(
showBottomSheetThenCalled
,
isTrue
);
...
...
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