scroll_configuration.dart 3.12 KB
Newer Older
1 2 3 4
// 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.

5 6
import 'package:meta/meta.dart';

7 8 9
import 'framework.dart';
import 'scroll_behavior.dart';

10 11 12
/// Controls how [Scrollable] widgets in a subtree behave.
///
/// Used by [ScrollConfiguration].
13
class ScrollConfigurationDelegate {
14 15 16
  /// Creates a delegate with sensible default behaviors.
  const ScrollConfigurationDelegate();

17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
  /// 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;
}

33
/// A widget that controls descendant [Scrollable] widgets.
34 35 36
///
/// Classes that create Scrollables are not required to depend on this
/// Widget. The following general purpose scrolling widgets do depend
37 38 39
/// on [ScrollConfiguration]: [Block], [LazyBlock], [ScrollableViewport],
/// [ScrollableList], [ScrollableLazyList]. The [Scrollable] base class uses
/// [ScrollConfiguration] to create its [ScrollBehavior].
40
class ScrollConfiguration extends InheritedWidget {
41 42 43 44 45
  /// 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].
46 47 48
  ScrollConfiguration({
    Key key,
    this.delegate,
49
    @required Widget child
50 51
  }) : super(key: key, child: child);

52
  static const ScrollConfigurationDelegate _defaultDelegate = const ScrollConfigurationDelegate();
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76

  /// 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;
  }
}