Skip to content

Commit

Permalink
Merge pull request #55 from TatsuUkraine/release-4.0.1
Browse files Browse the repository at this point in the history
Release 4.0.1 -> master
  • Loading branch information
TatsuUkraine authored Apr 18, 2021
2 parents 5e63c96 + 7eaa87d commit ab23608
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 56 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## [4.0.1] - 2021-04-19

- implement missing dry layout calculation

## [4.0.0] - 2021-03-01

- stable null-safety release
Expand Down
153 changes: 98 additions & 55 deletions lib/render.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class StickyListItemRenderObject<I> extends RenderStack {
double? _lastOffset;
bool _headerOverflow = false;

ClipRectLayer? _clipRectLayer;

StickyListItemRenderObject({
required ScrollableState scrollable,
required I itemIndex,
Expand Down Expand Up @@ -144,55 +146,87 @@ class StickyListItemRenderObject<I> extends RenderStack {

@override
void paint(PaintingContext context, Offset paintOffset) {
updateHeaderOffset();
_updateHeaderOffset();

if (clipBehavior != Clip.none && _headerOverflow) {
context.pushClipRect(
_clipRectLayer = context.pushClipRect(
needsCompositing, paintOffset, Offset.zero & size, paintStack,
clipBehavior: clipBehavior);
clipBehavior: clipBehavior, oldLayer: _clipRectLayer);
} else {
_clipRectLayer = null;
paintStack(context, paintOffset);
}
}

@override
Size computeDryLayout(BoxConstraints constraints) {
return _computeSize(
constraints: constraints,
layoutChild: ChildLayoutHelper.dryLayoutChild,
);
}

@override
void performLayout() {
final BoxConstraints constraints = this.constraints;
final RenderBox header = _headerBox;

double constraintWidth = constraints.minWidth;
double constraintHeight = constraints.minHeight;
size = _computeSize(
constraints: constraints,
layoutChild: ChildLayoutHelper.layoutChild,
);

final RenderBox header = _headerBox;

final BoxConstraints containerConstraints = constraints.loosen();

header.layout(containerConstraints, parentUsesSize: true);

final Size containerSize =
_layoutContent(containerConstraints, header.size);
final StackParentData headerParentData =
header.parentData as StackParentData;
final StackParentData contentParentData =
_contentBox.parentData as StackParentData;

headerParentData.offset = alignment
.resolve(TextDirection.ltr)
.alongOffset(size - header.size as Offset);

contentParentData.offset = _offsetContent(header.size);
}

Size _computeSize({
required BoxConstraints constraints,
required ChildLayouter layoutChild,
}) {
final double constraintWidth = constraints.minWidth;
final double constraintHeight = constraints.minHeight;

final BoxConstraints containerConstraints = constraints.loosen();

final Size headerSize = layoutChild(_headerBox, containerConstraints);

final Size containerSize = _layoutContent(
constraints: containerConstraints,
headerSize: headerSize,
layoutChild: layoutChild,
);

size = Size(max(constraintWidth, containerSize.width),
final Size size = Size(max(constraintWidth, containerSize.width),
max(constraintHeight, containerSize.height));

assert(size.width == constraints.constrainWidth(size.width));
assert(size.height == constraints.constrainHeight(size.height));

assert(size.isFinite);

final StackParentData headerParentData =
header.parentData as StackParentData;

headerParentData.offset = alignment
.resolve(TextDirection.ltr)
.alongOffset(size - header.size as Offset);
return size;
}

void updateHeaderOffset() {
void _updateHeaderOffset() {
_headerOverflow = false;

final double stuckOffset = _stuckOffset;

final StackParentData parentData =
_headerBox.parentData as StackParentData;
final StackParentData parentData = _headerBox.parentData as StackParentData;
final double contentSize = _contentDirectionSize;
final double headerSize = _headerDirectionSize;

Expand All @@ -206,8 +240,8 @@ class StickyListItemRenderObject<I> extends RenderStack {
contentSize: contentSize,
);

final double headerOffset = _calculateHeaderOffset(contentSize, stuckOffset,
headerSize, minOffsetProvider(state));
final double headerOffset = _calculateHeaderOffset(
contentSize, stuckOffset, headerSize, minOffsetProvider(state));

parentData.offset =
_headerDirectionalOffset(parentData.offset, headerOffset);
Expand Down Expand Up @@ -272,11 +306,11 @@ class StickyListItemRenderObject<I> extends RenderStack {
_positionAxis == HeaderPositionAxis.crossAxis ||
!_scrollDirectionVertical &&
_positionAxis == HeaderPositionAxis.mainAxis) {
return _contentBox.getMinIntrinsicHeight(width);
return _contentBox.getMaxIntrinsicHeight(width);
}

return _contentBox.getMinIntrinsicHeight(width) +
_headerBox.getMinIntrinsicHeight(width);
return _contentBox.getMaxIntrinsicHeight(width) +
_headerBox.getMaxIntrinsicHeight(width);
}

bool get _scrollDirectionVertical =>
Expand Down Expand Up @@ -322,9 +356,8 @@ class StickyListItemRenderObject<I> extends RenderStack {
double get _contentDirectionSize =>
_scrollDirectionVertical ? size.height : size.width;

double get _headerDirectionSize => _scrollDirectionVertical
? _headerBox.size.height
: _headerBox.size.width;
double get _headerDirectionSize =>
_scrollDirectionVertical ? _headerBox.size.height : _headerBox.size.width;

Offset _headerDirectionalOffset(Offset originalOffset, double offset) {
if (_scrollDirectionVertical) {
Expand Down Expand Up @@ -386,34 +419,26 @@ class StickyListItemRenderObject<I> extends RenderStack {
state.position < 1);
}

Size _layoutContent(BoxConstraints constraints, Size headerSize) {
Size _layoutContent({
required BoxConstraints constraints,
required Size headerSize,
required ChildLayouter layoutChild,
}) {
final RenderBox content = _contentBox;
final StackParentData contentParentData =
content.parentData as StackParentData;
contentParentData.offset = Offset.zero;

if (!_overlayContent) {
if ((_positionAxis == HeaderPositionAxis.crossAxis &&
_scrollDirectionVertical) ||
(_positionAxis == HeaderPositionAxis.mainAxis &&
!_scrollDirectionVertical)) {
content.layout(
final Size contentSize = layoutChild(
content,
constraints.copyWith(
maxWidth: constraints.maxWidth - headerSize.width,
minHeight: headerSize.height,
),
parentUsesSize: true,
);

if ((_crossAxisAlignment == HeaderCrossAxisAlignment.start &&
_scrollDirectionVertical) ||
(_mainAxisAlignment == HeaderMainAxisAlignment.start &&
!_scrollDirectionVertical)) {
contentParentData.offset = Offset(headerSize.width, 0);
}

final Size contentSize = content.size;

return Size(contentSize.width + headerSize.width,
max(contentSize.height, headerSize.height));
}
Expand All @@ -422,43 +447,61 @@ class StickyListItemRenderObject<I> extends RenderStack {
_scrollDirectionVertical) ||
(_positionAxis == HeaderPositionAxis.crossAxis &&
!_scrollDirectionVertical)) {
content.layout(
final Size contentSize = layoutChild(
content,
constraints.copyWith(
maxHeight: constraints.maxHeight - headerSize.height,
minWidth: headerSize.width,
),
parentUsesSize: true,
);

if ((_mainAxisAlignment == HeaderMainAxisAlignment.start &&
_scrollDirectionVertical) ||
(_crossAxisAlignment == HeaderCrossAxisAlignment.start &&
!_scrollDirectionVertical)) {
contentParentData.offset = Offset(0, headerSize.height);
}

final Size contentSize = content.size;

return Size(max(contentSize.width, headerSize.width),
contentSize.height + headerSize.height);
}
}

content.layout(
final Size contentSize = layoutChild(
content,
constraints.copyWith(
minHeight: headerSize.height,
minWidth: headerSize.width,
),
parentUsesSize: true,
);
final Size contentSize = content.size;

return Size(
max(contentSize.width, headerSize.width),
max(contentSize.height, headerSize.height),
);
}

Offset _offsetContent(Size headerSize) {
if (!_overlayContent) {
if (((_positionAxis == HeaderPositionAxis.crossAxis &&
_scrollDirectionVertical) ||
(_positionAxis == HeaderPositionAxis.mainAxis &&
!_scrollDirectionVertical)) &&
((_crossAxisAlignment == HeaderCrossAxisAlignment.start &&
_scrollDirectionVertical) ||
(_mainAxisAlignment == HeaderMainAxisAlignment.start &&
!_scrollDirectionVertical))) {
return Offset(headerSize.width, 0);
}

if (((_positionAxis == HeaderPositionAxis.mainAxis &&
_scrollDirectionVertical) ||
(_positionAxis == HeaderPositionAxis.crossAxis &&
!_scrollDirectionVertical)) &&
((_mainAxisAlignment == HeaderMainAxisAlignment.start &&
_scrollDirectionVertical) ||
(_crossAxisAlignment == HeaderCrossAxisAlignment.start &&
!_scrollDirectionVertical))) {
return Offset(0, headerSize.height);
}
}

return Offset.zero;
}

static AlignmentGeometry _headerAlignment(
ScrollableState scrollable,
HeaderMainAxisAlignment mainAxisAlignment,
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: >-
Can be customized or with config options or with override.
version: 4.0.0
version: 4.0.1
homepage: https://github.com/TatsuUkraine/flutter_sticky_infinite_list
repository: https://github.com/TatsuUkraine/flutter_sticky_infinite_list
issue_tracker: https://github.com/TatsuUkraine/flutter_sticky_infinite_list/issues
Expand Down

0 comments on commit ab23608

Please sign in to comment.