Commit ba5a04e8 authored by Hans Muller's avatar Hans Muller

ClampOverscrolls Inherited Widget (#3267)

* ClampOverscrolls Inherited Widget
parent 8849cd6b
...@@ -194,7 +194,6 @@ class ListDemoState extends State<ListDemo> { ...@@ -194,7 +194,6 @@ class ListDemoState extends State<ListDemo> {
child: new MaterialList( child: new MaterialList(
type: _itemType, type: _itemType,
scrollablePadding: new EdgeInsets.all(_dense ? 4.0 : 8.0), scrollablePadding: new EdgeInsets.all(_dense ? 4.0 : 8.0),
clampOverscrolls: true,
children: listItems children: listItems
) )
) )
......
...@@ -24,7 +24,6 @@ class MaterialList extends StatefulWidget { ...@@ -24,7 +24,6 @@ class MaterialList extends StatefulWidget {
this.initialScrollOffset, this.initialScrollOffset,
this.onScroll, this.onScroll,
this.type: MaterialListType.twoLine, this.type: MaterialListType.twoLine,
this.clampOverscrolls: false,
this.children, this.children,
this.scrollablePadding: EdgeInsets.zero, this.scrollablePadding: EdgeInsets.zero,
this.scrollableKey this.scrollableKey
...@@ -33,7 +32,6 @@ class MaterialList extends StatefulWidget { ...@@ -33,7 +32,6 @@ class MaterialList extends StatefulWidget {
final double initialScrollOffset; final double initialScrollOffset;
final ScrollListener onScroll; final ScrollListener onScroll;
final MaterialListType type; final MaterialListType type;
final bool clampOverscrolls;
final Iterable<Widget> children; final Iterable<Widget> children;
final EdgeInsets scrollablePadding; final EdgeInsets scrollablePadding;
final Key scrollableKey; final Key scrollableKey;
...@@ -49,7 +47,6 @@ class _MaterialListState extends State<MaterialList> { ...@@ -49,7 +47,6 @@ class _MaterialListState extends State<MaterialList> {
key: config.scrollableKey, key: config.scrollableKey,
initialScrollOffset: config.initialScrollOffset, initialScrollOffset: config.initialScrollOffset,
scrollDirection: Axis.vertical, scrollDirection: Axis.vertical,
clampOverscrolls: config.clampOverscrolls,
onScroll: config.onScroll, onScroll: config.onScroll,
itemExtent: kListItemExtent[config.type], itemExtent: kListItemExtent[config.type],
padding: const EdgeInsets.symmetric(vertical: 8.0) + config.scrollablePadding, padding: const EdgeInsets.symmetric(vertical: 8.0) + config.scrollablePadding,
......
...@@ -202,7 +202,10 @@ class _OverscrollIndicatorState extends State<OverscrollIndicator> { ...@@ -202,7 +202,10 @@ class _OverscrollIndicatorState extends State<OverscrollIndicator> {
child: child child: child
); );
}, },
child: config.child child: new ClampOverscrolls(
child: config.child,
value: true
)
) )
); );
} }
......
...@@ -90,7 +90,7 @@ abstract class ExtentScrollBehavior extends ScrollBehavior<double, double> { ...@@ -90,7 +90,7 @@ abstract class ExtentScrollBehavior extends ScrollBehavior<double, double> {
void debugFillDescription(List<String> description) { void debugFillDescription(List<String> description) {
super.debugFillDescription(description); super.debugFillDescription(description);
description.add('content: ${contentExtent.toStringAsFixed(1)}'); description.add('content: ${contentExtent.toStringAsFixed(1)}');
description.add('container: ${contentExtent.toStringAsFixed(1)}'); description.add('container: ${containerExtent.toStringAsFixed(1)}');
description.add('range: ${minScrollOffset?.toStringAsFixed(1)} .. ${maxScrollOffset?.toStringAsFixed(1)}'); description.add('range: ${minScrollOffset?.toStringAsFixed(1)} .. ${maxScrollOffset?.toStringAsFixed(1)}');
} }
} }
......
...@@ -11,6 +11,40 @@ import 'virtual_viewport.dart'; ...@@ -11,6 +11,40 @@ import 'virtual_viewport.dart';
import 'package:flutter/rendering.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 Scrollable { class ScrollableList extends Scrollable {
ScrollableList({ ScrollableList({
Key key, Key key,
...@@ -21,7 +55,6 @@ class ScrollableList extends Scrollable { ...@@ -21,7 +55,6 @@ class ScrollableList extends Scrollable {
SnapOffsetCallback snapOffsetCallback, SnapOffsetCallback snapOffsetCallback,
this.itemExtent, this.itemExtent,
this.itemsWrap: false, this.itemsWrap: false,
this.clampOverscrolls: false,
this.padding, this.padding,
this.children this.children
}) : super( }) : super(
...@@ -37,7 +70,6 @@ class ScrollableList extends Scrollable { ...@@ -37,7 +70,6 @@ class ScrollableList extends Scrollable {
final double itemExtent; final double itemExtent;
final bool itemsWrap; final bool itemsWrap;
final bool clampOverscrolls;
final EdgeInsets padding; final EdgeInsets padding;
final Iterable<Widget> children; final Iterable<Widget> children;
...@@ -64,10 +96,11 @@ class _ScrollableListState extends ScrollableState<ScrollableList> { ...@@ -64,10 +96,11 @@ class _ScrollableListState extends ScrollableState<ScrollableList> {
@override @override
Widget buildContent(BuildContext context) { Widget buildContent(BuildContext context) {
final double listScrollOffset = config.clampOverscrolls final bool clampOverscrolls = ClampOverscrolls.of(context);
final double listScrollOffset = clampOverscrolls
? scrollOffset.clamp(scrollBehavior.minScrollOffset, scrollBehavior.maxScrollOffset) ? scrollOffset.clamp(scrollBehavior.minScrollOffset, scrollBehavior.maxScrollOffset)
: scrollOffset; : scrollOffset;
return new ListViewport( Widget viewport = new ListViewport(
onExtentsChanged: _handleExtentsChanged, onExtentsChanged: _handleExtentsChanged,
scrollOffset: listScrollOffset, scrollOffset: listScrollOffset,
mainAxis: config.scrollDirection, mainAxis: config.scrollDirection,
...@@ -77,6 +110,9 @@ class _ScrollableListState extends ScrollableState<ScrollableList> { ...@@ -77,6 +110,9 @@ class _ScrollableListState extends ScrollableState<ScrollableList> {
padding: config.padding, padding: config.padding,
children: config.children children: config.children
); );
if (clampOverscrolls)
viewport = new ClampOverscrolls(value: false, child: viewport);
return viewport;
} }
} }
......
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