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
f53d0fec
Commit
f53d0fec
authored
May 24, 2017
by
Ian Hickson
Committed by
GitHub
May 24, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add some documentation for RenderSliver. (#10272)
parent
51ba6b37
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
155 additions
and
22 deletions
+155
-22
sliver.dart
packages/flutter/lib/src/rendering/sliver.dart
+155
-22
No files found.
packages/flutter/lib/src/rendering/sliver.dart
View file @
f53d0fec
...
...
@@ -763,18 +763,141 @@ String _debugCompareFloats(String labelA, double valueA, String labelB, double v
'apply the min() or max() functions, or the clamp() method, to the
$labelB
? '
;
}
// ///
// /// ## Writing a RenderSliver subclass
// ///
// /// ### Painting
// ///
// /// The [paint] method is called with an [Offset] to the top-left corner of the
// /// sliver, _regardless of the axis direction_.
// ///
// /// ### childScrollOffset
// ///
// /// If the subclass positions children anywhere other than at scroll offset
// /// 0.0, you need to override [childScrollOffset]...
/// Base class for the render objects that implement scroll effects in viewports.
///
/// A [RenderViewport] has a list of child slivers. Each sliver — literally a
/// slice of the viewport's contents — is laid out in turn, covering the
/// viewport in the process. (Every sliver is laid out each time, including
/// those that have zero extent because they are "scrolled off" or are beyond
/// the end of the viewport.)
///
/// Slivers participate in the _sliver protocol_, wherein during [layout] each
/// sliver receives a [SliverConstraints] object and computes a corresponding
/// [SliverGeometry] that describes where it fits in the viewport. This is
/// analogous to the box protocol used by [RenderBox], which gets a
/// [BoxConstraints] as input and computes a [Size].
///
/// Slivers have a leading edge, which is where the position described by
/// [SliverConstraints.scrollOffset] for this sliver begins. Slivers have
/// several dimensions, the primary of which is [SliverGeometry.paintExtent],
/// which describes the extent of the sliver along the main axis, starting from
/// the leading edge, reaching either the end of the viewport or the end of the
/// sliver, whichever comes first.
///
/// Slivers can change dimensions based on the changing constraints in a
/// non-linear fashion, to achieve various scroll effects. For example, the
/// various [RenderSliverPersistentHeader] subclasses, on which [SliverAppBar]
/// is based, achieve effects such as staying visible despite the scroll offset,
/// or reappearing at different offsets based on the user's scroll direction
/// ([SliverConstraints.userScrollDirection]).
///
/// ## Writing a RenderSliver subclass
///
/// Slivers can have sliver children, or children from another coordinate
/// system, typically box children. (For details on the box protocol, see
/// [RenderBox].) Slivers can also have different child models, typically having
/// either one child, or a list of children.
///
/// ### Examples of slivers
///
/// A good example of a sliver with a single child that is also itself a sliver
/// is [RenderSliverPadding], which indents its child. A sliver-to-sliver render
/// object such as this must construct a [SliverConstraints] object for its
/// child, then must take its child's [SliverGeometry] and use it to form its
/// own [geometry].
///
/// The other common kind of one-child sliver is a sliver that has a single
/// [RenderBox] child. An example of that would be [RenderSliverToBoxAdapter],
/// which lays out a single box and sizes itself around the box. Such a sliver
/// must use its [SliverConstraints] to create a [BoxConstraints] for the
/// child, lay the child out (using the child's [layout] method), and then use
/// the child's [RenderBox.size] to generate the sliver's [SliverGeometry].
///
/// The most common kind of sliver though is one with multiple children. The
/// most straight-forward example of this is [RenderSliverList], which arranges
/// its children one after the other in the main axis direction. As with the
/// one-box-child sliver case, it uses its [constraints] to create a
/// [BoxConstraints] for the children, and then it uses the aggregate
/// information from all its children to generate its [geometry]. Unlike the
/// one-child cases, however, it is judicious in which children it actually lays
/// out (and later paints). If the scroll offset is 1000 pixels, and it
/// previously determined that the first three children are each 400 pixels
/// tall, then it will skip the first two and start the layout with its third
/// child.
///
/// ### Layout
///
/// As they are laid out, slivers decide their [geometry], which includes their
/// size ([SliverGeometry.paintExtent]) and the position of the next sliver
/// ([SliverGeometry.layoutExtent]), as well as the position of each of their
/// children, based on the input [constraints] from the viewport such as the
/// scroll offset ([SliverConstraints.scrollOffset]).
///
/// For example, a sliver that just paints a box 100 pixels high would say its
/// [SliverGeometry.paintExtent] was 100 pixels when the scroll offset was zero,
/// but would say its [SliverGeometry.paintExtent] was 25 pixels when the scroll
/// offset was 75 pixels, and would say it was zero when the scroll offset was
/// 100 pixels or more. (This is assuming that
/// [SliverConstraints.remainingPaintExtent] was more than 100 pixels.)
///
/// The various dimensions that are provided as input to this system are in the
/// [constraints]. They are described in detail in the documentation for the
/// [SliverConstraints] class.
///
/// The [performLayout] function must take these [constraints] and create a
/// [SliverGeometry] object that it must then assign to the [geometry] property.
/// The different dimensions of the geometry that can be configured are
/// described in detail in the documentation for the [SliverGeometry] class.
///
/// ### Painting
///
/// In addition to implementing layout, a sliver must also implement painting.
/// This is achieved by overriding the [paint] method.
///
/// The [paint] method is called with an [Offset] from the [Canvas] origin to
/// the top-left corner of the sliver, _regardless of the axis direction_.
///
/// Subclasses should also override [applyPaintTransform] to provide the
/// [Matrix4] describing the position of each child relative to the sliver.
/// (This is used by, among other things, the accessibility layer, to determine
/// the bounds of the child.)
///
/// ### Hit testing
///
/// To implement hit testing, either override the [hitTestSelf] and
/// [hitTestChildren] methods, or, for more complex cases, instead override the
/// [hitTest] method directly.
///
/// To actually react to pointer events, the [handleEvent] method may be
/// implemented. By default it does nothing. (Typically gestures are handled by
/// widgets in the box protocol, not by slivers directly.)
///
/// ### Helper methods
///
/// There are a number of methods that a sliver should implement which will make
/// the other methods easier to implement. Each method listed below has detailed
/// documentation. In addition, the [RenderSliverHelpers] class can be used to
/// mix in some helpful methods.
///
/// #### childScrollOffset
///
/// If the subclass positions children anywhere other than at scroll offset
/// zero, it should override [childScrollOffset]. For example,
/// [RenderSliverList] and [RenderSliverGrid] override this method, but
/// [RenderSliverToBoxAdapter] does not.
///
/// This is used by, among other things, [Scrollable.ensureVisible].
///
/// #### childMainAxisPosition
///
/// Subclasses should implement [childMainAxisPosition] to describe where their
/// children are positioned.
///
/// #### childCrossAxisPosition
///
/// If the subclass positions children in the cross-axis at a position other
/// than zero, then it should override [childCrossAxisPosition]. For example
/// [RenderSliverGrid] overrides this method.
abstract
class
RenderSliver
extends
RenderObject
{
// layout input
@override
...
...
@@ -925,6 +1048,12 @@ abstract class RenderSliver extends RenderObject {
/// vertical (i.e. the [SliverConstraints.axisDirection] is either
/// [AxisDirection.right] or [AxisDirection.left]), then the
/// `crossAxisPosition` is a distance from the top edge of the sliver.
///
/// ## Implementing hit testing for slivers
///
/// The most straight-forward way to implement hit testing for a new sliver
/// render object is to override its [hitTestSelf] and [hitTestChildren]
/// methods.
bool
hitTest
(
HitTestResult
result
,
{
@required
double
mainAxisPosition
,
@required
double
crossAxisPosition
})
{
if
(
mainAxisPosition
>=
0.0
&&
mainAxisPosition
<
geometry
.
hitTestExtent
&&
crossAxisPosition
>=
0.0
&&
crossAxisPosition
<
constraints
.
crossAxisExtent
)
{
...
...
@@ -980,6 +1109,8 @@ abstract class RenderSliver extends RenderObject {
/// sliver always paints the same amount but consumes a scroll offset extent
/// that is proportional to the [SliverConstraints.scrollOffset], then this
/// function's results will not be consistent.
// This could be a static method but isn't, because it would be less convenient
// to call it from subclasses if it was.
double
calculatePaintOffset
(
SliverConstraints
constraints
,
{
@required
double
from
,
@required
double
to
})
{
assert
(
from
<=
to
);
final
double
a
=
constraints
.
scrollOffset
;
...
...
@@ -1001,8 +1132,6 @@ abstract class RenderSliver extends RenderObject {
/// [SliverConstraints.scrollOffset] and
/// [SliverLogicalParentData.layoutOffset].
///
/// Calling this for a child that is not visible is not valid.
///
/// For children that are [RenderSliver]s, the leading edge of the _child_
/// will be the leading _visible_ edge of the child, not the part of the child
/// that would locally be a scroll offset 0.0. For children that are not
...
...
@@ -1010,14 +1139,12 @@ abstract class RenderSliver extends RenderObject {
/// to the edge of the box, since those boxes do not know how to handle being
/// scrolled.
///
/// This is used by [RenderSliverHelpers.hitTestBoxChild]. If you do not use
/// the [RenderSliverHelpers] mixin and do not call this method yourself, you
/// do not need to implement this method.
///
/// This method differs from [childScrollOffset] in that
/// [childMainAxisPosition] gives the distance from the leading _visible_ edge
/// of the sliver whereas [childScrollOffset] gives the distance from sliver's
/// zero scroll offset.
/// of the sliver whereas [childScrollOffset] gives the distance from the
/// sliver's zero scroll offset.
///
/// Calling this for a child that is not visible is not valid.
@protected
double
childMainAxisPosition
(
covariant
RenderObject
child
)
{
assert
(()
{
...
...
@@ -1027,13 +1154,16 @@ abstract class RenderSliver extends RenderObject {
}
/// Returns the distance along the cross axis from the zero of the cross axis
/// to the nearest side of the given child.
/// in this sliver's [paint] coordinate space to the nearest side of the given
/// child.
///
/// For example, if the [constraints] describe this sliver as having an axis
/// direction of [AxisDirection.down], then this is the distance from the left
/// of the sliver to the left of the child. Similarly, if the [constraints]
/// describe this sliver as having an axis direction of [AxisDirection.up],
/// then this is value is the same.
/// then this is value is the same. If the axis direction is
/// [AxisDirection.left] or [AxisDirection.right], then it is the distance
/// from the top of the sliver to the top of the child.
///
/// Calling this for a child that is not visible is not valid.
@protected
...
...
@@ -1062,6 +1192,8 @@ abstract class RenderSliver extends RenderObject {
/// This returns a [Size] with dimensions relative to the leading edge of the
/// sliver, specifically the same offset that is given to the [paint] method.
/// This means that the dimensions may be negative.
///
/// This is only valid after [layout] has completed.
@protected
Size
getAbsoluteSizeRelativeToOrigin
()
{
assert
(
geometry
!=
null
);
...
...
@@ -1183,6 +1315,7 @@ abstract class RenderSliver extends RenderObject {
});
}
// This override exists only to change the type of the second argument.
@override
void
handleEvent
(
PointerEvent
event
,
SliverHitTestEntry
entry
)
{
}
...
...
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