Commit cddf06cf authored by Hans Muller's avatar Hans Muller Committed by GitHub

Added scroll snapping to the gallery animation demo (#9710)

parent 6a4b08be
...@@ -365,6 +365,64 @@ class _AllSectionsView extends AnimatedWidget { ...@@ -365,6 +365,64 @@ class _AllSectionsView extends AnimatedWidget {
} }
} }
// Support snapping scrolls to the midScrollOffset: the point at which the
// 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);
final double midScrollOffset;
@override
_SnappingScrollPhysics applyTo(ScrollPhysics parent) {
return new _SnappingScrollPhysics(
parent: parent,
midScrollOffset: midScrollOffset
);
}
Simulation _toMidScrollOffsetSimulation(double offset, double dragVelocity) {
final double velocity = math.max(dragVelocity, minFlingVelocity);
return new ScrollSpringSimulation(spring, offset, midScrollOffset, velocity, tolerance: tolerance);
}
Simulation _toZeroScrollOffsetSimulation(double offset, double dragVelocity) {
final double velocity = math.max(dragVelocity, minFlingVelocity);
return new ScrollSpringSimulation(spring, offset, 0.0, velocity, tolerance: tolerance);
}
@override
Simulation createBallisticSimulation(ScrollMetrics position, double dragVelocity) {
final Simulation simulation = super.createBallisticSimulation(position, dragVelocity);
final double offset = position.pixels;
if (simulation != null) {
// The drag ended with sufficient velocity to trigger creating a simulation.
// If the simulation is headed up towards midScrollOffset but will not reach it,
// then snap it there. Similarly if the simulation is headed down past
// midScrollOffset but will not reach zero, then snap it to zero.
final double simulationEnd = simulation.x(double.INFINITY);
if (simulationEnd >= midScrollOffset)
return simulation;
if (dragVelocity > 0.0)
return _toMidScrollOffsetSimulation(offset, dragVelocity);
if (dragVelocity < 0.0)
return _toZeroScrollOffsetSimulation(offset, dragVelocity);
} else {
// The user ended the drag with little or no velocity. If they
// didn't leave the the offset above midScrollOffset, then
// snap to midScrollOffset if they're more than halfway there,
// otherwise snap to zero.
final double snapThreshold = midScrollOffset / 2.0;
if (offset >= snapThreshold && offset < midScrollOffset)
return _toMidScrollOffsetSimulation(offset, dragVelocity);
if (offset > 0.0 && offset < snapThreshold)
return _toZeroScrollOffsetSimulation(offset, dragVelocity);
}
return simulation;
}
}
class AnimationDemoHome extends StatefulWidget { class AnimationDemoHome extends StatefulWidget {
const AnimationDemoHome({ Key key }) : super(key: key); const AnimationDemoHome({ Key key }) : super(key: key);
...@@ -478,6 +536,7 @@ class _AnimationDemoHomeState extends State<AnimationDemoHome> { ...@@ -478,6 +536,7 @@ class _AnimationDemoHomeState extends State<AnimationDemoHome> {
children: <Widget>[ children: <Widget>[
new CustomScrollView( new CustomScrollView(
controller: _scrollController, controller: _scrollController,
physics: new _SnappingScrollPhysics(midScrollOffset: appBarMidScrollOffset),
slivers: <Widget>[ slivers: <Widget>[
// Start out below the status bar, gradually move to the top of the screen. // Start out below the status bar, gradually move to the top of the screen.
new _StatusBarPaddingSliver( new _StatusBarPaddingSliver(
......
...@@ -13,7 +13,7 @@ import 'overscroll_indicator.dart'; ...@@ -13,7 +13,7 @@ import 'overscroll_indicator.dart';
import 'scroll_metrics.dart'; import 'scroll_metrics.dart';
import 'scroll_simulation.dart'; import 'scroll_simulation.dart';
export 'package:flutter/physics.dart' show Tolerance; export 'package:flutter/physics.dart' show Simulation, ScrollSpringSimulation, Tolerance;
/// Determines the physics of a [Scrollable] widget. /// Determines the physics of a [Scrollable] widget.
/// ///
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment