relative_stack 0.0.4 relative_stack: ^0.0.4 copied to clipboard
A widget that you could stack the children list by specifying their relative positions
Features #
You could use RelativeStack
to position its children relative to you specify widget. (the specified widget is also one of the children list)
tag 1
would be relative toRelativeStack
self, and its center would be overlapped at the center ofRelativeStack
tag 2
would be relative totag 1
, and itsbottomRight
would be overlapped at thetopLeft
oftag 1
tag 3
would be also relative totag 1
, and itstopLeft
would be overlapped at thecenter
oftag 1
and be shiftedOffset(-10, 10)
absolutelytag 4
would be relative toRelativeStack
self, and itstopRight
would be aligned to thetopRight
ofRelativeStack
tag 5
would be also relative totag 1
, and itstopCenter
would be aligned to thebottomCenter
oftag 1
tag 6
is not wrapped inRelativePositioned
, so it would be treated as a normal widget and painted from thetopLeft
ofRelativeStack
By using AnimatedRelative
, you could animate your widget's position like AnimatedPositioned
:
Questions #
Why RelativePositioned
/AnimatedRelative
is overflowing #
Truly, the RelativePositioned
widgets may be outside of the Size
of RelativeStack
(overflowing) because they would only follow their RelativePositioned.relativeTo
instead of relative to RelativeStack
directly. Only those RelativePositioned
that have no relativeTo
property would be relative to RelativeStack
directly.
Why the AnimatedRelative
or RelativePositioned
does not trigger gesture tapping events #
If the AnimatedRelative
or RelativePositioned
is painted at the outside of the size of RelativeStack
(it is possible because RelativeStack
only ensure the widgets follow its target's position but not guarantee they are inside of its size), it cannot pass the hitTest
due to the mechanism of Flutter hitTest:
Why AnimatedRelative
would change the size of RelativeStack
#
since the size of RelativeStack
is computed as below, so its size might be change during animation
How the size of RelativeStack
is computed #
Since the children list may contain normal widgets and RelativePositioned
, so we follow the below rules to compute the size of RelativeStack
.
- For all
RelativePositioned
widgets, we would abstract them as multi-node tree according to their relations defined byRelativePositioned.relativeTo
. Afterlayout
each render box, we could know their actual size, and then, we go through their relation trees to compute their relativeSize
s. Finally, we would compare theRelativeSize
of each relation tree by:
_RelativeSize compare(_RelativeSize other) {
return _RelativeSize()
..top = min(top, other.top)
..left = min(left, other.left)
..right = max(right, other.right)
..bottom = max(bottom, other.bottom);
}
to determine the maximum Size
for all relation trees.
- for normal widgets, we do not need to process them particularly, and we could know their actual sizes instantly once
layout
them.
Once we get all Size
s ready, we could compare them to determine the final Size
for RelativeStack
:
double width = idealRelativeSize.size.width;
double height = idealRelativeSize.size.height;
while (nonRelativeSizes.isNotEmpty) {
final childSize = nonRelativeSizes.removeLast();
width = max(childSize.width, width);
height = max(childSize.height, height);
}
size = constraints.constrain(Size(width, height));