| /// 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 'package:meta/meta.dart'; |
| import 'package:flutter/foundation.dart'; |
| |
| import 'framework.dart'; |
| import 'scroll_behavior.dart'; |
| |
| /// Controls how [Scrollable] widgets in a subtree behave. |
| /// |
| /// Used by [ScrollConfiguration]. |
| abstract class ScrollConfigurationDelegate { |
| /// Abstract const constructor. This constructor enables subclasses to provide |
| /// const constructors so that they can be used in const expressions. |
| const ScrollConfigurationDelegate(); |
| |
| /// Returns the platform whose scroll physics should be approximated. See |
| /// [ScrollBehavior.platform]. |
| TargetPlatform get platform; |
| |
| /// Returns the ScrollBehavior to be used by generic scrolling containers like |
| /// [Block]. |
| ExtentScrollBehavior createScrollBehavior(); |
| |
| /// 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(BuildContext context, Widget scrollWidget) => scrollWidget; |
| |
| /// Overrides should return true if this ScrollConfigurationDelegate differs |
| /// from the provided old delegate in a way that requires rebuilding its |
| /// scrolling container descendants. |
| bool updateShouldNotify(ScrollConfigurationDelegate old); |
| } |
| |
| class _DefaultScrollConfigurationDelegate extends ScrollConfigurationDelegate { |
| const _DefaultScrollConfigurationDelegate(); |
| |
| @override |
| TargetPlatform get platform => defaultTargetPlatform; |
| |
| @override |
| ExtentScrollBehavior createScrollBehavior() => new OverscrollWhenScrollableBehavior(platform: platform); |
| |
| @override |
| bool updateShouldNotify(ScrollConfigurationDelegate old) => false; |
| } |
| |
| /// A widget that controls descendant [Scrollable] widgets. |
| /// |
| /// 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 { |
| /// Creates a widget that controls descendant [Scrollable] widgets. |
| /// |
| /// If the [delegate] argument is null, the scroll configuration for this |
| /// subtree is controlled by the default implementation of |
| /// [ScrollConfigurationDelegate]. |
| ScrollConfiguration({ |
| Key key, |
| this.delegate, |
| @required Widget child |
| }) : super(key: key, child: child); |
| |
| static const ScrollConfigurationDelegate _defaultDelegate = const _DefaultScrollConfigurationDelegate(); |
| |
| /// 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 a default |
| /// [ScrollConfigurationDelegate] that approximates the scrolling physics of |
| /// the current platform (see [defaultTargetPlatform]) using a |
| /// [OverscrollWhenScrollableBehavior] behavior model. |
| 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 ScrollConfiguration.of(context).wrapScrollWidget(context, scrollWidget); |
| } |
| |
| @override |
| bool updateShouldNotify(ScrollConfiguration old) { |
| return delegate?.updateShouldNotify(old.delegate) ?? false; |
| } |
| } |