retrieveCommonStackAlignment function
AlignmentModel
retrieveCommonStackAlignment(
- BaseNode parent,
- List<BaseNode> nodes
)
Implementation
AlignmentModel retrieveCommonStackAlignment(
BaseNode parent,
List<BaseNode> nodes,
) {
final List<AlignmentModel> alignments = [];
if (nodes.length == 1 &&
nodes.single is ScrollableMixin &&
(nodes.single as ScrollableMixin).isScrollable) {
return AlignmentModel.none;
}
for (final BaseNode node in nodes) {
final AlignmentModel alignment = node.alignment;
if (alignment.data == null) continue;
alignments.add(alignment);
}
final AlignmentModel? mostCommonAlignment;
if (alignments.isEmpty) {
mostCommonAlignment = null;
} else {
mostCommonAlignment = mostCommon<AlignmentModel>(alignments);
}
AlignmentModel? bestAlignment = mostCommonAlignment;
// mostCommonAlignment will be null if a tie exists. In such cases, we
// completely disregard common alignment and use an Align widget on each child
// as it is higher quality, more readable code. While that works most of the
// time, if the stack is wrapping in any axis, all [Align]ed children will be
// converted into [Positioned] widgets to prevent the Stack from expanding
// instead of wrapping.
//
// With that in mind, if all of the children are Positioned in a wrapping
// Stack, the Stack will implode on itself as it has no concrete,
// non-Positioned children and to figure out its first-pass size. The
// Positioned children end up in a zero-size Stack as a result.
//
// To fix this specific situation, we arbitrarily return one of the tied
// alignments. The stack will use this alignment for its `stackAlignment`
// property, which does not expand the stack, rather aligns children
// correctly instead. Once we pass this stack alignment, the singular child
// that this alignment matches is not going to wrap itself with an Align
// widget because its alignment matches the stack alignment. This means that
// the stack will have a concrete child to figure out its size and will not
// implode. The rest of the children will be wrapped with Positioned widgets
// in a Stack that has a concrete size.
if (bestAlignment == null &&
parent.isOneOrBothWrap &&
alignments.isNotEmpty) {
bestAlignment = getLargestNodeForWrappingStack(parent, nodes)?.alignment;
}
return bestAlignment ?? AlignmentModel.none;
}