Add dartdoc to VirtualViewport widgets
This commit is contained in:
parent
3cb4984909
commit
24c0ab7f92
@ -9,20 +9,33 @@ import 'package:vector_math/vector_math_64.dart';
|
|||||||
import 'box.dart';
|
import 'box.dart';
|
||||||
import 'object.dart';
|
import 'object.dart';
|
||||||
|
|
||||||
|
/// The end of the viewport from which the paint offset is computed.
|
||||||
enum ViewportAnchor {
|
enum ViewportAnchor {
|
||||||
|
/// The start (e.g., top or left, depending on the axis) of the first item
|
||||||
|
/// should be aligned with the start (e.g., top or left, depending on the
|
||||||
|
/// axis) of the viewport.
|
||||||
start,
|
start,
|
||||||
|
|
||||||
|
/// The end (e.g., bottom or right, depending on the axis) of the last item
|
||||||
|
/// should be aligned with the end (e.g., bottom or right, depending on the
|
||||||
|
/// axis) of the viewport.
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The interior and exterior dimensions of a viewport.
|
||||||
class ViewportDimensions {
|
class ViewportDimensions {
|
||||||
const ViewportDimensions({
|
const ViewportDimensions({
|
||||||
this.contentSize: Size.zero,
|
this.contentSize: Size.zero,
|
||||||
this.containerSize: Size.zero
|
this.containerSize: Size.zero
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/// A viewport that has zero size, both inside and outside.
|
||||||
static const ViewportDimensions zero = const ViewportDimensions();
|
static const ViewportDimensions zero = const ViewportDimensions();
|
||||||
|
|
||||||
|
/// The size of the content inside the viewport.
|
||||||
final Size contentSize;
|
final Size contentSize;
|
||||||
|
|
||||||
|
/// The size of the outside of the viewport.
|
||||||
final Size containerSize;
|
final Size containerSize;
|
||||||
|
|
||||||
bool get _debugHasAtLeastOneCommonDimension {
|
bool get _debugHasAtLeastOneCommonDimension {
|
||||||
@ -30,6 +43,8 @@ class ViewportDimensions {
|
|||||||
|| contentSize.height == containerSize.height;
|
|| contentSize.height == containerSize.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the offset at which to paint the content, accounting for the given
|
||||||
|
/// anchor and the dimensions of the viewport.
|
||||||
Offset getAbsolutePaintOffset({ Offset paintOffset, ViewportAnchor anchor }) {
|
Offset getAbsolutePaintOffset({ Offset paintOffset, ViewportAnchor anchor }) {
|
||||||
assert(_debugHasAtLeastOneCommonDimension);
|
assert(_debugHasAtLeastOneCommonDimension);
|
||||||
switch (anchor) {
|
switch (anchor) {
|
||||||
@ -55,7 +70,9 @@ class ViewportDimensions {
|
|||||||
String toString() => 'ViewportDimensions(container: $containerSize, content: $contentSize)';
|
String toString() => 'ViewportDimensions(container: $containerSize, content: $contentSize)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An interface that indicates that an object has a scroll direction.
|
||||||
abstract class HasScrollDirection {
|
abstract class HasScrollDirection {
|
||||||
|
/// Whether this object scrolls horizontally or vertically.
|
||||||
Axis get scrollDirection;
|
Axis get scrollDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,6 +136,9 @@ class RenderViewportBase extends RenderBox implements HasScrollDirection {
|
|||||||
markNeedsLayout();
|
markNeedsLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The end of the viewport from which the paint offset is computed.
|
||||||
|
///
|
||||||
|
/// See [ViewportAnchor] for more detail.
|
||||||
ViewportAnchor get scrollAnchor => _scrollAnchor;
|
ViewportAnchor get scrollAnchor => _scrollAnchor;
|
||||||
ViewportAnchor _scrollAnchor;
|
ViewportAnchor _scrollAnchor;
|
||||||
void set scrollAnchor(ViewportAnchor value) {
|
void set scrollAnchor(ViewportAnchor value) {
|
||||||
|
@ -202,7 +202,7 @@ class PageableListState<T extends PageableList> extends ScrollableState<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PageViewport extends VirtualViewport with VirtualViewportIterableMixin {
|
class PageViewport extends VirtualViewportFromIterable {
|
||||||
PageViewport({
|
PageViewport({
|
||||||
this.startOffset: 0.0,
|
this.startOffset: 0.0,
|
||||||
this.scrollDirection: Axis.vertical,
|
this.scrollDirection: Axis.vertical,
|
||||||
|
@ -63,7 +63,7 @@ class _ScrollableGridState extends ScrollableState<ScrollableGrid> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class GridViewport extends VirtualViewport with VirtualViewportIterableMixin {
|
class GridViewport extends VirtualViewportFromIterable {
|
||||||
GridViewport({
|
GridViewport({
|
||||||
this.startOffset,
|
this.startOffset,
|
||||||
this.delegate,
|
this.delegate,
|
||||||
|
@ -240,7 +240,7 @@ class _VirtualListViewportElement extends VirtualViewportElement<_VirtualListVie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ListViewport extends _VirtualListViewport with VirtualViewportIterableMixin {
|
class ListViewport extends _VirtualListViewport with VirtualViewportFromIterable {
|
||||||
ListViewport({
|
ListViewport({
|
||||||
ExtentsChangedCallback onExtentsChanged,
|
ExtentsChangedCallback onExtentsChanged,
|
||||||
double scrollOffset: 0.0,
|
double scrollOffset: 0.0,
|
||||||
@ -350,7 +350,7 @@ class _ScrollableLazyListState extends ScrollableState<ScrollableLazyList> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LazyListViewport extends _VirtualListViewport with VirtualViewportLazyMixin {
|
class LazyListViewport extends _VirtualListViewport with VirtualViewportFromBuilder {
|
||||||
LazyListViewport({
|
LazyListViewport({
|
||||||
ExtentsChangedCallback onExtentsChanged,
|
ExtentsChangedCallback onExtentsChanged,
|
||||||
double scrollOffset: 0.0,
|
double scrollOffset: 0.0,
|
||||||
|
@ -11,7 +11,9 @@ import 'package:flutter/rendering.dart';
|
|||||||
|
|
||||||
typedef void ExtentsChangedCallback(double contentExtent, double containerExtent);
|
typedef void ExtentsChangedCallback(double contentExtent, double containerExtent);
|
||||||
|
|
||||||
|
/// An abstract widget whose children are not all materialized.
|
||||||
abstract class VirtualViewport extends RenderObjectWidget {
|
abstract class VirtualViewport extends RenderObjectWidget {
|
||||||
|
/// The offset from the [ViewportAnchor] at which the viewport should start painting children.
|
||||||
double get startOffset;
|
double get startOffset;
|
||||||
|
|
||||||
_WidgetProvider _createWidgetProvider();
|
_WidgetProvider _createWidgetProvider();
|
||||||
@ -24,12 +26,24 @@ abstract class _WidgetProvider {
|
|||||||
Widget getChild(int i);
|
Widget getChild(int i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Materializes a contiguous subset of its children.
|
||||||
|
///
|
||||||
|
/// This class is a building block for building a widget that has more children
|
||||||
|
/// than it wishes to display at any given time. For example, [ScrollableList]
|
||||||
|
/// uses this element to materialize only those children that are visible.
|
||||||
abstract class VirtualViewportElement<T extends VirtualViewport> extends RenderObjectElement<T> {
|
abstract class VirtualViewportElement<T extends VirtualViewport> extends RenderObjectElement<T> {
|
||||||
VirtualViewportElement(T widget) : super(widget);
|
VirtualViewportElement(T widget) : super(widget);
|
||||||
|
|
||||||
|
/// The index of the first child to materialize.
|
||||||
int get materializedChildBase;
|
int get materializedChildBase;
|
||||||
|
|
||||||
|
/// The number of children to materializes.
|
||||||
int get materializedChildCount;
|
int get materializedChildCount;
|
||||||
|
|
||||||
|
/// The least offset for which [materializedChildBase] and [materializedChildCount] are valid.
|
||||||
double get startOffsetBase;
|
double get startOffsetBase;
|
||||||
|
|
||||||
|
/// The greatest offset for which [materializedChildBase] and [materializedChildCount] are valid.
|
||||||
double get startOffsetLimit;
|
double get startOffsetLimit;
|
||||||
|
|
||||||
/// Returns the pixel offset for a scroll offset, accounting for the scroll
|
/// Returns the pixel offset for a scroll offset, accounting for the scroll
|
||||||
@ -124,6 +138,12 @@ abstract class VirtualViewportElement<T extends VirtualViewport> extends RenderO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Called by [RenderVirtualViewport] during layout.
|
||||||
|
///
|
||||||
|
/// Subclasses should override this function to compute [materializedChildBase]
|
||||||
|
/// and [materializedChildCount]. Overrides should call this function to
|
||||||
|
/// update the [RenderVirtualViewport]'s paint offset and to materialize the
|
||||||
|
/// children.
|
||||||
void layout(BoxConstraints constraints) {
|
void layout(BoxConstraints constraints) {
|
||||||
assert(startOffsetBase != null);
|
assert(startOffsetBase != null);
|
||||||
assert(startOffsetLimit != null);
|
assert(startOffsetLimit != null);
|
||||||
@ -162,7 +182,12 @@ abstract class VirtualViewportElement<T extends VirtualViewport> extends RenderO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class VirtualViewportIterableMixin extends VirtualViewport {
|
/// A VirtualViewport that represents its children using [Iterable<Widget>].
|
||||||
|
///
|
||||||
|
/// The iterator is advanced just far enough to obtain widgets for the children
|
||||||
|
/// that need to be materialized.
|
||||||
|
abstract class VirtualViewportFromIterable extends VirtualViewport {
|
||||||
|
/// The children, some of which might be materialized.
|
||||||
Iterable<Widget> get children;
|
Iterable<Widget> get children;
|
||||||
|
|
||||||
_IterableWidgetProvider _createWidgetProvider() => new _IterableWidgetProvider();
|
_IterableWidgetProvider _createWidgetProvider() => new _IterableWidgetProvider();
|
||||||
@ -173,7 +198,7 @@ class _IterableWidgetProvider extends _WidgetProvider {
|
|||||||
Iterator<Widget> _iterator;
|
Iterator<Widget> _iterator;
|
||||||
List<Widget> _widgets;
|
List<Widget> _widgets;
|
||||||
|
|
||||||
void didUpdateWidget(VirtualViewportIterableMixin oldWidget, VirtualViewportIterableMixin newWidget) {
|
void didUpdateWidget(VirtualViewportFromIterable oldWidget, VirtualViewportFromIterable newWidget) {
|
||||||
if (oldWidget == null || newWidget.children != oldWidget.children) {
|
if (oldWidget == null || newWidget.children != oldWidget.children) {
|
||||||
_iterator = null;
|
_iterator = null;
|
||||||
_widgets = <Widget>[];
|
_widgets = <Widget>[];
|
||||||
@ -187,7 +212,7 @@ class _IterableWidgetProvider extends _WidgetProvider {
|
|||||||
int limit = base < 0 ? _length : math.min(_length, base + count);
|
int limit = base < 0 ? _length : math.min(_length, base + count);
|
||||||
if (limit <= _widgets.length)
|
if (limit <= _widgets.length)
|
||||||
return;
|
return;
|
||||||
VirtualViewportIterableMixin widget = context.widget;
|
VirtualViewportFromIterable widget = context.widget;
|
||||||
if (widget.children is List<Widget>) {
|
if (widget.children is List<Widget>) {
|
||||||
_widgets = widget.children;
|
_widgets = widget.children;
|
||||||
return;
|
return;
|
||||||
@ -205,10 +230,21 @@ class _IterableWidgetProvider extends _WidgetProvider {
|
|||||||
Widget getChild(int i) => _widgets[(i % _length).abs()];
|
Widget getChild(int i) => _widgets[(i % _length).abs()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Signature of a callback that returns the sublist of widgets in the given range.
|
||||||
typedef List<Widget> ItemListBuilder(BuildContext context, int start, int count);
|
typedef List<Widget> ItemListBuilder(BuildContext context, int start, int count);
|
||||||
|
|
||||||
abstract class VirtualViewportLazyMixin extends VirtualViewport {
|
/// A VirtualViewport that represents its children using [ItemListBuilder].
|
||||||
|
///
|
||||||
|
/// This widget is less ergonomic than [VirtualViewportFromIterable] but scales to
|
||||||
|
/// unlimited numbers of children.
|
||||||
|
abstract class VirtualViewportFromBuilder extends VirtualViewport {
|
||||||
|
/// The total number of children that can be built.
|
||||||
int get itemCount;
|
int get itemCount;
|
||||||
|
|
||||||
|
/// A callback to build the subset of widgets that are needed to populate the
|
||||||
|
/// viewport. Not all of the returned widgets will actually be included in the
|
||||||
|
/// viewport (e.g., if we need to measure the size of non-visible children to
|
||||||
|
/// determine which children are visible).
|
||||||
ItemListBuilder get itemBuilder;
|
ItemListBuilder get itemBuilder;
|
||||||
|
|
||||||
_LazyWidgetProvider _createWidgetProvider() => new _LazyWidgetProvider();
|
_LazyWidgetProvider _createWidgetProvider() => new _LazyWidgetProvider();
|
||||||
@ -219,7 +255,7 @@ class _LazyWidgetProvider extends _WidgetProvider {
|
|||||||
int _base;
|
int _base;
|
||||||
List<Widget> _widgets;
|
List<Widget> _widgets;
|
||||||
|
|
||||||
void didUpdateWidget(VirtualViewportLazyMixin oldWidget, VirtualViewportLazyMixin newWidget) {
|
void didUpdateWidget(VirtualViewportFromBuilder oldWidget, VirtualViewportFromBuilder newWidget) {
|
||||||
if (_length != newWidget.itemCount || oldWidget?.itemBuilder != newWidget.itemBuilder) {
|
if (_length != newWidget.itemCount || oldWidget?.itemBuilder != newWidget.itemBuilder) {
|
||||||
_length = newWidget.itemCount;
|
_length = newWidget.itemCount;
|
||||||
_base = null;
|
_base = null;
|
||||||
@ -232,7 +268,7 @@ class _LazyWidgetProvider extends _WidgetProvider {
|
|||||||
void prepareChildren(VirtualViewportElement context, int base, int count) {
|
void prepareChildren(VirtualViewportElement context, int base, int count) {
|
||||||
if (_widgets != null && _widgets.length == count && _base == base)
|
if (_widgets != null && _widgets.length == count && _base == base)
|
||||||
return;
|
return;
|
||||||
VirtualViewportLazyMixin widget = context.widget;
|
VirtualViewportFromBuilder widget = context.widget;
|
||||||
_base = base;
|
_base = base;
|
||||||
_widgets = widget.itemBuilder(context, base, count);
|
_widgets = widget.itemBuilder(context, base, count);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user