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
1f06dc44
Commit
1f06dc44
authored
May 20, 2016
by
Hans Muller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ScrollConfiguration (#4026)
parent
10c861d6
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
235 additions
and
92 deletions
+235
-92
list_demo.dart
examples/flutter_gallery/lib/demo/list_demo.dart
+5
-7
overscroll_demo.dart
examples/flutter_gallery/lib/demo/overscroll_demo.dart
+16
-12
app.dart
packages/flutter/lib/src/material/app.dart
+14
-1
friction_simulation.dart
packages/flutter/lib/src/physics/friction_simulation.dart
+1
-1
basic.dart
packages/flutter/lib/src/widgets/basic.dart
+1
-0
clamp_overscrolls.dart
packages/flutter/lib/src/widgets/clamp_overscrolls.dart
+60
-0
lazy_block.dart
packages/flutter/lib/src/widgets/lazy_block.dart
+11
-11
scroll_behavior.dart
packages/flutter/lib/src/widgets/scroll_behavior.dart
+12
-1
scroll_configuration.dart
packages/flutter/lib/src/widgets/scroll_configuration.dart
+64
-0
scrollable.dart
packages/flutter/lib/src/widgets/scrollable.dart
+19
-6
scrollable_grid.dart
packages/flutter/lib/src/widgets/scrollable_grid.dart
+10
-3
scrollable_list.dart
packages/flutter/lib/src/widgets/scrollable_list.dart
+19
-49
widgets.dart
packages/flutter/lib/widgets.dart
+2
-0
snap_scrolling_test.dart
packages/flutter/test/widget/snap_scrolling_test.dart
+1
-1
No files found.
examples/flutter_gallery/lib/demo/list_demo.dart
View file @
1f06dc44
...
...
@@ -191,13 +191,11 @@ class ListDemoState extends State<ListDemo> {
)
]
),
body:
new
OverscrollIndicator
(
child:
new
Scrollbar
(
child:
new
MaterialList
(
type:
_itemType
,
padding:
new
EdgeInsets
.
symmetric
(
vertical:
_dense
?
4.0
:
8.0
),
children:
listItems
)
body:
new
Scrollbar
(
child:
new
MaterialList
(
type:
_itemType
,
padding:
new
EdgeInsets
.
symmetric
(
vertical:
_dense
?
4.0
:
8.0
),
children:
listItems
)
)
);
...
...
examples/flutter_gallery/lib/demo/overscroll_demo.dart
View file @
1f06dc44
...
...
@@ -43,17 +43,22 @@ class OverscrollDemoState extends State<OverscrollDemo> {
break
;
}
Widget
body
=
new
MaterialList
(
type:
MaterialListType
.
threeLine
,
padding:
const
EdgeInsets
.
all
(
8.0
),
children:
_items
.
map
((
String
item
)
{
return
new
ListItem
(
isThreeLine:
true
,
leading:
new
CircleAvatar
(
child:
new
Text
(
item
)),
title:
new
Text
(
'This item represents
$item
.'
),
subtitle:
new
Text
(
'Even more additional list item information appears on line three.'
)
);
})
// The default ScrollConfiguration doesn't include the
// OverscrollIndicator. That's what we want, since this demo
// adds the OverscrollIndicator itself.
Widget
body
=
new
ScrollConfiguration
(
child:
new
MaterialList
(
type:
MaterialListType
.
threeLine
,
padding:
const
EdgeInsets
.
all
(
8.0
),
children:
_items
.
map
((
String
item
)
{
return
new
ListItem
(
isThreeLine:
true
,
leading:
new
CircleAvatar
(
child:
new
Text
(
item
)),
title:
new
Text
(
'This item represents
$item
.'
),
subtitle:
new
Text
(
'Even more additional list item information appears on line three.'
)
);
})
)
);
switch
(
_type
)
{
case
IndicatorType
.
overscroll
:
...
...
@@ -91,5 +96,4 @@ class OverscrollDemoState extends State<OverscrollDemo> {
body:
body
);
}
}
packages/flutter/lib/src/material/app.dart
View file @
1f06dc44
...
...
@@ -2,10 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:io'
show
Platform
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/widgets.dart'
;
import
'colors.dart'
;
import
'overscroll_indicator.dart'
;
import
'page.dart'
;
import
'theme.dart'
;
...
...
@@ -141,6 +144,13 @@ class MaterialApp extends StatefulWidget {
_MaterialAppState
createState
()
=>
new
_MaterialAppState
();
}
class
_IndicatorScrollConfigurationDelegate
extends
ScrollConfigurationDelegate
{
@override
Widget
wrapScrollWidget
(
Widget
scrollWidget
)
=>
new
OverscrollIndicator
(
child:
scrollWidget
);
}
final
ScrollConfigurationDelegate
_indicatorScroll
=
new
_IndicatorScrollConfigurationDelegate
();
final
ScrollConfigurationDelegate
_bounceScroll
=
new
ScrollConfigurationDelegate
();
class
_MaterialAppState
extends
State
<
MaterialApp
>
{
final
HeroController
_heroController
=
new
HeroController
();
...
...
@@ -190,6 +200,9 @@ class _MaterialAppState extends State<MaterialApp> {
return
true
;
});
return
result
;
return
new
ScrollConfiguration
(
delegate:
(
Platform
.
isIOS
||
Platform
.
isMacOS
)
?
_bounceScroll
:
_indicatorScroll
,
child:
result
);
}
}
packages/flutter/lib/src/physics/friction_simulation.dart
View file @
1f06dc44
...
...
@@ -36,7 +36,7 @@ class FrictionSimulation extends Simulation {
/// velocity, and the velocities must be in the direction appropriate for the
/// particle to start from the start position and reach the end position.
factory
FrictionSimulation
.
through
(
double
startPosition
,
double
endPosition
,
double
startVelocity
,
double
endVelocity
)
{
assert
(
startVelocity
.
sign
==
endVelocity
.
sign
);
assert
(
startVelocity
==
0.0
||
endVelocity
==
0.0
||
startVelocity
.
sign
==
endVelocity
.
sign
);
assert
(
startVelocity
.
abs
()
>=
endVelocity
.
abs
());
assert
((
endPosition
-
startPosition
).
sign
==
startVelocity
.
sign
);
return
new
FrictionSimulation
(
...
...
packages/flutter/lib/src/widgets/basic.dart
View file @
1f06dc44
...
...
@@ -47,6 +47,7 @@ export 'package:flutter/rendering.dart' show
SingleChildLayoutDelegate
,
TextOverflow
,
ValueChanged
,
ValueGetter
,
ViewportAnchor
,
ViewportDimensions
,
ViewportDimensionsChangeCallback
;
...
...
packages/flutter/lib/src/widgets/clamp_overscrolls.dart
0 → 100644
View file @
1f06dc44
// Copyright 2016 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
'framework.dart'
;
import
'scrollable.dart'
;
typedef
Widget
ViewportBuilder
(
BuildContext
context
,
ScrollableState
state
,
double
scrollOffset
);
/// If true, the ClampOverscroll's [Scrollable] descendant will clamp its
/// viewport's scrollOffsets to the [ScrollBehavior]'s min and max values.
/// In this case the Scrollable's scrollOffset will still over- and undershoot
/// the ScrollBehavior's limits, but the viewport itself will not.
class
ClampOverscrolls
extends
InheritedWidget
{
ClampOverscrolls
({
Key
key
,
this
.
value
,
Widget
child
})
:
super
(
key:
key
,
child:
child
)
{
assert
(
value
!=
null
);
assert
(
child
!=
null
);
}
/// True if the [Scrollable] descendant should clamp its viewport's scrollOffset
/// values when they are less than the [ScrollBehavior]'s minimum or greater than
/// its maximum.
final
bool
value
;
static
bool
of
(
BuildContext
context
)
{
final
ClampOverscrolls
result
=
context
.
inheritFromWidgetOfExactType
(
ClampOverscrolls
);
return
result
?.
value
??
false
;
}
/// If ClampOverscrolls is true, clamps the ScrollableState's scrollOffset to the
/// [ScrollBehavior] minimum and maximum values and then constructs the viewport
/// with the clamped scrollOffset. ClampOverscrolls is reset to false for viewport
/// descendants.
///
/// This utility function is typically used by [Scrollable.builder] callbacks.
static
Widget
buildViewport
(
BuildContext
context
,
ScrollableState
state
,
ViewportBuilder
builder
)
{
final
bool
clampOverscrolls
=
ClampOverscrolls
.
of
(
context
);
final
double
clampedScrollOffset
=
clampOverscrolls
?
state
.
scrollOffset
.
clamp
(
state
.
scrollBehavior
.
minScrollOffset
,
state
.
scrollBehavior
.
maxScrollOffset
)
:
state
.
scrollOffset
;
Widget
viewport
=
builder
(
context
,
state
,
clampedScrollOffset
);
if
(
clampOverscrolls
)
viewport
=
new
ClampOverscrolls
(
value:
false
,
child:
viewport
);
return
viewport
;
}
@override
bool
updateShouldNotify
(
ClampOverscrolls
old
)
=>
value
!=
old
.
value
;
@override
void
debugFillDescription
(
List
<
String
>
description
)
{
super
.
debugFillDescription
(
description
);
description
.
add
(
'value:
$value
'
);
}
}
packages/flutter/lib/src/widgets/lazy_block.dart
View file @
1f06dc44
...
...
@@ -7,7 +7,9 @@ import 'dart:math' as math;
import
'package:flutter/rendering.dart'
;
import
'basic.dart'
;
import
'clamp_overscrolls.dart'
;
import
'framework.dart'
;
import
'scroll_configuration.dart'
;
import
'scrollable.dart'
;
import
'scrollable_list.dart'
;
import
'scroll_behavior.dart'
;
...
...
@@ -205,13 +207,9 @@ class LazyBlock extends StatelessWidget {
});
}
Widget
_buildContent
(
BuildContext
context
,
ScrollableState
state
)
{
final
bool
clampOverscrolls
=
ClampOverscrolls
.
of
(
context
);
final
double
startOffset
=
clampOverscrolls
?
state
.
scrollOffset
.
clamp
(
state
.
scrollBehavior
.
minScrollOffset
,
state
.
scrollBehavior
.
maxScrollOffset
)
:
state
.
scrollOffset
;
Widget
viewport
=
new
LazyBlockViewport
(
startOffset:
startOffset
,
Widget
_buildViewport
(
BuildContext
context
,
ScrollableState
state
,
double
scrollOffset
)
{
return
new
LazyBlockViewport
(
startOffset:
scrollOffset
,
mainAxis:
scrollDirection
,
padding:
padding
,
onExtentsChanged:
(
double
contentExtent
,
double
containerExtent
,
double
minScrollOffset
)
{
...
...
@@ -219,14 +217,15 @@ class LazyBlock extends StatelessWidget {
},
delegate:
delegate
);
if
(
clampOverscrolls
)
viewport
=
new
ClampOverscrolls
(
value:
false
,
child:
viewport
);
return
viewport
;
}
Widget
_buildContent
(
BuildContext
context
,
ScrollableState
state
)
{
return
ClampOverscrolls
.
buildViewport
(
context
,
state
,
_buildViewport
);
}
@override
Widget
build
(
BuildContext
context
)
{
return
new
Scrollable
(
final
Widget
result
=
new
Scrollable
(
key:
scrollableKey
,
initialScrollOffset:
initialScrollOffset
,
scrollDirection:
scrollDirection
,
...
...
@@ -236,6 +235,7 @@ class LazyBlock extends StatelessWidget {
snapOffsetCallback:
snapOffsetCallback
,
builder:
_buildContent
);
return
ScrollConfiguration
.
wrap
(
context
,
result
);
}
}
...
...
packages/flutter/lib/src/widgets/scroll_behavior.dart
View file @
1f06dc44
...
...
@@ -9,6 +9,11 @@ import 'package:flutter/physics.dart';
const
double
_kSecondsPerMillisecond
=
1000.0
;
const
double
_kScrollDrag
=
0.025
;
// TODO(hansmuller): Simplify these classes. We're no longer using the ScrollBehavior<T, U>
// base class directly. Only LazyBlock uses BoundedBehavior's updateExtents minScrollOffset
// parameter; simpler to move that into ExtentScrollBehavior. All of the classes should
// be called FooScrollBehavior.
/// An interface for controlling the behavior of scrollable widgets.
///
/// The type argument T is the type that describes the scroll offset.
...
...
@@ -220,8 +225,14 @@ class OverscrollWhenScrollableBehavior extends OverscrollBehavior {
@override
Simulation
createScrollSimulation
(
double
position
,
double
velocity
)
{
if
(
isScrollable
||
position
<
minScrollOffset
||
position
>
maxScrollOffset
)
if
(
isScrollable
||
position
<
minScrollOffset
||
position
>
maxScrollOffset
)
{
// If the triggering gesture starts at or beyond the contentExtent's limits
// then the simulation only serves to settle the scrollOffset back to its
// minimum or maximum value.
if
(
position
<
minScrollOffset
||
position
>
maxScrollOffset
)
velocity
=
0.0
;
return
super
.
createScrollSimulation
(
position
,
velocity
);
}
return
null
;
}
...
...
packages/flutter/lib/src/widgets/scroll_configuration.dart
0 → 100644
View file @
1f06dc44
// Copyright 2016 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
'framework.dart'
;
import
'scroll_behavior.dart'
;
class
ScrollConfigurationDelegate
{
/// Returns the ScrollBehavior to be used by generic scrolling containers like
/// [Block]. Returns a new [OverscrollWhenScrollableBehavior] by default.
ExtentScrollBehavior
createScrollBehavior
()
=>
new
OverscrollWhenScrollableBehavior
();
/// Generic scrolling containers like [Block] will apply this function to the
/// Scrollable they create. It can be used to add widgets that wrap the
/// Scrollable, like scrollbars or overscroll indicators. By default the
/// [scrollWidget] parameter is returned unchanged.
Widget
wrapScrollWidget
(
Widget
scrollWidget
)
=>
scrollWidget
;
/// Overrides should return true if the this ScrollConfigurationDelegate has
/// changed in a way that requires rebuilding its scrolling container descendants.
/// Returns false by default.
bool
updateShouldNotify
(
ScrollConfigurationDelegate
old
)
=>
false
;
}
/// Used by descendants to initialize and wrap the [Scrollable] widgets
/// they create.
///
/// Classes that create Scrollables are not required to depend on this
/// Widget. The following general purpose scrolling widgets do depend
/// on ScrollConfiguration: Block, LazyBlock, ScrollableViewport,
/// ScrollableList, ScrollableLazyList. The Scrollable base class uses
/// ScrollConfiguration to create its [ScrollBehavior].
class
ScrollConfiguration
extends
InheritedWidget
{
ScrollConfiguration
({
Key
key
,
this
.
delegate
,
Widget
child
})
:
super
(
key:
key
,
child:
child
);
static
final
ScrollConfigurationDelegate
_defaultDelegate
=
new
ScrollConfigurationDelegate
();
/// Defines the ScrollBehavior and scrollable wrapper for descendants.
final
ScrollConfigurationDelegate
delegate
;
/// The delegate property of the closest instance of this class that encloses
/// the given context.
///
/// If no such instance exists, returns an instance of the
/// [ScrollConfigurationDelegate] base class.
static
ScrollConfigurationDelegate
of
(
BuildContext
context
)
{
ScrollConfiguration
configuration
=
context
.
inheritFromWidgetOfExactType
(
ScrollConfiguration
);
return
configuration
?.
delegate
??
_defaultDelegate
;
}
/// A utility function that calls [ScrollConfigurationDelegate.wrapScrollWidget].
static
Widget
wrap
(
BuildContext
context
,
Widget
scrollWidget
)
{
return
of
(
context
).
wrapScrollWidget
(
scrollWidget
);
}
@override
bool
updateShouldNotify
(
ScrollConfiguration
old
)
{
return
delegate
?.
updateShouldNotify
(
old
.
delegate
)
??
false
;
}
}
packages/flutter/lib/src/widgets/scrollable.dart
View file @
1f06dc44
...
...
@@ -11,11 +11,13 @@ import 'package:flutter/gestures.dart';
import
'package:meta/meta.dart'
;
import
'basic.dart'
;
import
'clamp_overscrolls.dart'
;
import
'framework.dart'
;
import
'gesture_detector.dart'
;
import
'notification_listener.dart'
;
import
'page_storage.dart'
;
import
'scroll_behavior.dart'
;
import
'scroll_configuration.dart'
;
/// The accuracy to which scrolling is computed.
final
Tolerance
kPixelScrollTolerance
=
new
Tolerance
(
...
...
@@ -319,9 +321,15 @@ class ScrollableState<T extends Scrollable> extends State<T> {
}
ExtentScrollBehavior
_scrollBehavior
;
/// Subclasses should override this function to create the [ScrollBehavior]
/// they desire.
ExtentScrollBehavior
createScrollBehavior
()
=>
new
OverscrollWhenScrollableBehavior
();
/// Use the value returned by [ScrollConfiguration.createScrollBehavior].
/// If this widget doesn't have a ScrollConfiguration ancestor,
/// or its createScrollBehavior callback is null, then return a new instance
/// of [OverscrollWhenScrollableBehavior].
ExtentScrollBehavior
createScrollBehavior
()
{
// TODO(hansmuller): this will not be called when the ScrollConfiguration changes.
// An override of dependenciesChanged() is probably needed.
return
ScrollConfiguration
.
of
(
context
)?.
createScrollBehavior
();
}
bool
_scrollOffsetIsInBounds
(
double
scrollOffset
)
{
if
(
scrollBehavior
is
!
ExtentScrollBehavior
)
...
...
@@ -773,9 +781,9 @@ class _ScrollableViewportState extends State<ScrollableViewport> {
return
state
.
scrollOffsetToPixelDelta
(
state
.
scrollOffset
);
}
Widget
_build
Content
(
BuildContext
context
,
ScrollableState
state
)
{
Widget
_build
Viewport
(
BuildContext
context
,
ScrollableState
state
,
double
scrollOffset
)
{
return
new
Viewport
(
paintOffset:
state
.
scrollOffsetToPixelDelta
(
s
tate
.
s
crollOffset
),
paintOffset:
state
.
scrollOffsetToPixelDelta
(
scrollOffset
),
mainAxis:
config
.
scrollDirection
,
anchor:
config
.
scrollAnchor
,
onPaintOffsetUpdateNeeded:
(
ViewportDimensions
dimensions
)
{
...
...
@@ -785,9 +793,13 @@ class _ScrollableViewportState extends State<ScrollableViewport> {
);
}
Widget
_buildContent
(
BuildContext
context
,
ScrollableState
state
)
{
return
ClampOverscrolls
.
buildViewport
(
context
,
state
,
_buildViewport
);
}
@override
Widget
build
(
BuildContext
context
)
{
return
new
Scrollable
(
final
Widget
result
=
new
Scrollable
(
key:
config
.
scrollableKey
,
initialScrollOffset:
config
.
initialScrollOffset
,
scrollDirection:
config
.
scrollDirection
,
...
...
@@ -798,6 +810,7 @@ class _ScrollableViewportState extends State<ScrollableViewport> {
snapOffsetCallback:
config
.
snapOffsetCallback
,
builder:
_buildContent
);
return
ScrollConfiguration
.
wrap
(
context
,
result
);
}
}
...
...
packages/flutter/lib/src/widgets/scrollable_grid.dart
View file @
1f06dc44
...
...
@@ -7,7 +7,9 @@ import 'dart:math' as math;
import
'package:collection/collection.dart'
show
lowerBound
;
import
'package:flutter/rendering.dart'
;
import
'clamp_overscrolls.dart'
;
import
'framework.dart'
;
import
'scroll_configuration.dart'
;
import
'scrollable.dart'
;
import
'virtual_viewport.dart'
;
...
...
@@ -74,9 +76,9 @@ class ScrollableGrid extends StatelessWidget {
});
}
Widget
_build
Content
(
BuildContext
context
,
ScrollableState
state
)
{
Widget
_build
Viewport
(
BuildContext
context
,
ScrollableState
state
,
double
scrollOffset
)
{
return
new
GridViewport
(
startOffset:
s
tate
.
s
crollOffset
,
startOffset:
scrollOffset
,
delegate:
delegate
,
onExtentsChanged:
(
double
contentExtent
,
double
containerExtent
)
{
_handleExtentsChanged
(
state
,
contentExtent
,
containerExtent
);
...
...
@@ -85,9 +87,13 @@ class ScrollableGrid extends StatelessWidget {
);
}
Widget
_buildContent
(
BuildContext
context
,
ScrollableState
state
)
{
return
ClampOverscrolls
.
buildViewport
(
context
,
state
,
_buildViewport
);
}
@override
Widget
build
(
BuildContext
context
)
{
return
new
Scrollable
(
final
Widget
result
=
new
Scrollable
(
key:
scrollableKey
,
initialScrollOffset:
initialScrollOffset
,
// TODO(abarth): Support horizontal offsets. For horizontally scrolling
...
...
@@ -100,6 +106,7 @@ class ScrollableGrid extends StatelessWidget {
snapOffsetCallback:
snapOffsetCallback
,
builder:
_buildContent
);
return
ScrollConfiguration
.
wrap
(
context
,
result
);
}
}
...
...
packages/flutter/lib/src/widgets/scrollable_list.dart
View file @
1f06dc44
...
...
@@ -4,47 +4,14 @@
import
'dart:math'
as
math
;
import
'clamp_overscrolls.dart'
;
import
'framework.dart'
;
import
'scroll_
behavior
.dart'
;
import
'scroll_
configuration
.dart'
;
import
'scrollable.dart'
;
import
'virtual_viewport.dart'
;
import
'package:flutter/rendering.dart'
;
/// If true, the ClampOverscroll's [Scrollable] descendant will clamp its
/// viewport's scrollOffsets to the [ScrollBehavior]'s min and max values.
/// In this case the Scrollable's scrollOffset will still over and undershoot
/// the ScrollBehavior's limits, but the viewport itself will not.
class
ClampOverscrolls
extends
InheritedWidget
{
ClampOverscrolls
({
Key
key
,
this
.
value
,
Widget
child
})
:
super
(
key:
key
,
child:
child
)
{
assert
(
value
!=
null
);
assert
(
child
!=
null
);
}
/// True if the [Scrollable] descendant should clamp its viewport's scrollOffset
/// values when they are less than the [ScrollBehavior]'s minimum or greater than
/// its maximum.
final
bool
value
;
static
bool
of
(
BuildContext
context
)
{
final
ClampOverscrolls
result
=
context
.
inheritFromWidgetOfExactType
(
ClampOverscrolls
);
return
result
?.
value
??
false
;
}
@override
bool
updateShouldNotify
(
ClampOverscrolls
old
)
=>
value
!=
old
.
value
;
@override
void
debugFillDescription
(
List
<
String
>
description
)
{
super
.
debugFillDescription
(
description
);
description
.
add
(
'value:
$value
'
);
}
}
class
ScrollableList
extends
StatelessWidget
{
ScrollableList
({
Key
key
,
...
...
@@ -144,16 +111,12 @@ class ScrollableList extends StatelessWidget {
});
}
Widget
_buildContent
(
BuildContext
context
,
ScrollableState
state
)
{
final
bool
clampOverscrolls
=
ClampOverscrolls
.
of
(
context
);
final
double
listScrollOffset
=
clampOverscrolls
?
state
.
scrollOffset
.
clamp
(
state
.
scrollBehavior
.
minScrollOffset
,
state
.
scrollBehavior
.
maxScrollOffset
)
:
state
.
scrollOffset
;
Widget
viewport
=
new
ListViewport
(
Widget
_buildViewport
(
BuildContext
context
,
ScrollableState
state
,
double
scrollOffset
)
{
return
new
ListViewport
(
onExtentsChanged:
(
double
contentExtent
,
double
containerExtent
)
{
_handleExtentsChanged
(
state
,
contentExtent
,
containerExtent
);
},
scrollOffset:
listS
crollOffset
,
scrollOffset:
s
crollOffset
,
mainAxis:
scrollDirection
,
anchor:
scrollAnchor
,
itemExtent:
itemExtent
,
...
...
@@ -161,14 +124,15 @@ class ScrollableList extends StatelessWidget {
padding:
padding
,
children:
children
);
if
(
clampOverscrolls
)
viewport
=
new
ClampOverscrolls
(
value:
false
,
child:
viewport
);
return
viewport
;
}
Widget
_buildContent
(
BuildContext
context
,
ScrollableState
state
)
{
return
ClampOverscrolls
.
buildViewport
(
context
,
state
,
_buildViewport
);
}
@override
Widget
build
(
BuildContext
context
)
{
return
new
Scrollable
(
final
Widget
result
=
new
Scrollable
(
key:
scrollableKey
,
initialScrollOffset:
initialScrollOffset
,
scrollDirection:
scrollDirection
,
...
...
@@ -179,6 +143,7 @@ class ScrollableList extends StatelessWidget {
snapOffsetCallback:
snapOffsetCallback
,
builder:
_buildContent
);
return
ScrollConfiguration
.
wrap
(
context
,
result
);
}
}
...
...
@@ -477,12 +442,12 @@ class ScrollableLazyList extends StatelessWidget {
});
}
Widget
_build
Content
(
BuildContext
context
,
ScrollableState
state
)
{
Widget
_build
Viewport
(
BuildContext
context
,
ScrollableState
state
,
double
scrollOffset
)
{
return
new
LazyListViewport
(
onExtentsChanged:
(
double
contentExtent
,
double
containerExtent
)
{
_handleExtentsChanged
(
state
,
contentExtent
,
containerExtent
);
},
scrollOffset:
s
tate
.
s
crollOffset
,
scrollOffset:
scrollOffset
,
mainAxis:
scrollDirection
,
anchor:
scrollAnchor
,
itemExtent:
itemExtent
,
...
...
@@ -492,9 +457,13 @@ class ScrollableLazyList extends StatelessWidget {
);
}
Widget
_buildContent
(
BuildContext
context
,
ScrollableState
state
)
{
return
ClampOverscrolls
.
buildViewport
(
context
,
state
,
_buildViewport
);
}
@override
Widget
build
(
BuildContext
context
)
{
return
new
Scrollable
(
final
Widget
result
=
new
Scrollable
(
key:
scrollableKey
,
initialScrollOffset:
initialScrollOffset
,
scrollDirection:
scrollDirection
,
...
...
@@ -505,6 +474,7 @@ class ScrollableLazyList extends StatelessWidget {
snapOffsetCallback:
snapOffsetCallback
,
builder:
_buildContent
);
return
ScrollConfiguration
.
wrap
(
context
,
result
);
}
}
...
...
packages/flutter/lib/widgets.dart
View file @
1f06dc44
...
...
@@ -15,6 +15,7 @@ export 'src/widgets/banner.dart';
export
'src/widgets/basic.dart'
;
export
'src/widgets/binding.dart'
;
export
'src/widgets/child_view.dart'
;
export
'src/widgets/clamp_overscrolls.dart'
;
export
'src/widgets/debug.dart'
;
export
'src/widgets/dismissable.dart'
;
export
'src/widgets/drag_target.dart'
;
...
...
@@ -43,6 +44,7 @@ export 'src/widgets/placeholder.dart';
export
'src/widgets/raw_keyboard_listener.dart'
;
export
'src/widgets/routes.dart'
;
export
'src/widgets/scroll_behavior.dart'
;
export
'src/widgets/scroll_configuration.dart'
;
export
'src/widgets/scrollable_grid.dart'
;
export
'src/widgets/scrollable_list.dart'
;
export
'src/widgets/scrollable.dart'
;
...
...
packages/flutter/test/widget/snap_scrolling_test.dart
View file @
1f06dc44
...
...
@@ -60,7 +60,7 @@ void main() {
Duration
dt
=
const
Duration
(
seconds:
2
);
fling
(
0.8
);
fling
(
1.0
);
await
tester
.
pump
();
// Start the scheduler at 0.0
await
tester
.
pump
(
dt
);
expect
(
scrollOffset
,
closeTo
(
200.0
,
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