Fix assertion failure when reordering two dimensional children (#141504)
It fixes assertion failure due to unstable state of children list during reordering in `RenderTwoDimensionalViewport.parentDataOf`. This changes the assertion to check debug orphan list and `keepAlive` bucket in addition to children list to determine whether child belongs to this render object or not. - Fixes #141101
This commit is contained in:
parent
aaa3eba12d
commit
a5ad088f7b
@ -779,8 +779,11 @@ abstract class RenderTwoDimensionalViewport extends RenderBox implements RenderA
|
|||||||
/// Children must have a [ParentData] of type
|
/// Children must have a [ParentData] of type
|
||||||
/// [TwoDimensionalViewportParentData], or a subclass thereof.
|
/// [TwoDimensionalViewportParentData], or a subclass thereof.
|
||||||
@protected
|
@protected
|
||||||
|
@mustCallSuper
|
||||||
TwoDimensionalViewportParentData parentDataOf(RenderBox child) {
|
TwoDimensionalViewportParentData parentDataOf(RenderBox child) {
|
||||||
assert(_children.containsValue(child));
|
assert(_children.containsValue(child) ||
|
||||||
|
_keepAliveBucket.containsValue(child) ||
|
||||||
|
_debugOrphans!.contains(child));
|
||||||
return child.parentData! as TwoDimensionalViewportParentData;
|
return child.parentData! as TwoDimensionalViewportParentData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,7 +195,7 @@ class RenderSimpleBuilderTableViewport extends RenderTwoDimensionalViewport {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
TestExtendedParentData parentDataOf(RenderBox child) {
|
TestExtendedParentData parentDataOf(RenderBox child) {
|
||||||
return child.parentData! as TestExtendedParentData;
|
return super.parentDataOf(child) as TestExtendedParentData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -2711,6 +2711,54 @@ void main() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('correctly reorders children and wont throw assertion failure',
|
||||||
|
(WidgetTester tester) async {
|
||||||
|
final TwoDimensionalChildBuilderDelegate delegate1 =
|
||||||
|
TwoDimensionalChildBuilderDelegate(
|
||||||
|
maxXIndex: 5,
|
||||||
|
maxYIndex: 5,
|
||||||
|
addAutomaticKeepAlives: false,
|
||||||
|
addRepaintBoundaries: false,
|
||||||
|
builder: (BuildContext context, ChildVicinity vicinity) {
|
||||||
|
ValueKey<int>? key;
|
||||||
|
if (vicinity == const ChildVicinity(xIndex: 1, yIndex: 1)) {
|
||||||
|
key = const ValueKey<int>(1);
|
||||||
|
} else if (vicinity ==
|
||||||
|
const ChildVicinity(xIndex: 1, yIndex: 2)) {
|
||||||
|
key = const ValueKey<int>(2);
|
||||||
|
}
|
||||||
|
return SizedBox.square(key: key, dimension: 200);
|
||||||
|
});
|
||||||
|
final TwoDimensionalChildBuilderDelegate delegate2 =
|
||||||
|
TwoDimensionalChildBuilderDelegate(
|
||||||
|
maxXIndex: 5,
|
||||||
|
maxYIndex: 5,
|
||||||
|
addAutomaticKeepAlives: false,
|
||||||
|
addRepaintBoundaries: false,
|
||||||
|
builder: (BuildContext context, ChildVicinity vicinity) {
|
||||||
|
ValueKey<int>? key;
|
||||||
|
if (vicinity == const ChildVicinity(xIndex: 0, yIndex: 0)) {
|
||||||
|
key = const ValueKey<int>(1);
|
||||||
|
} else if (vicinity ==
|
||||||
|
const ChildVicinity(xIndex: 1, yIndex: 1)) {
|
||||||
|
key = const ValueKey<int>(2);
|
||||||
|
}
|
||||||
|
return SizedBox.square(key: key, dimension: 200);
|
||||||
|
});
|
||||||
|
addTearDown(delegate1.dispose);
|
||||||
|
addTearDown(delegate2.dispose);
|
||||||
|
|
||||||
|
await tester.pumpWidget(simpleBuilderTest(delegate: delegate1));
|
||||||
|
expect(tester.getRect(find.byKey(const ValueKey<int>(1))),
|
||||||
|
const Rect.fromLTWH(200.0, 200.0, 200.0, 200.0));
|
||||||
|
await tester.pumpWidget(simpleBuilderTest(delegate: delegate2));
|
||||||
|
expect(tester.getRect(find.byKey(const ValueKey<int>(1))),
|
||||||
|
const Rect.fromLTWH(0.0, 0.0, 200.0, 200.0));
|
||||||
|
await tester.pumpWidget(simpleBuilderTest(delegate: delegate1));
|
||||||
|
expect(tester.getRect(find.byKey(const ValueKey<int>(1))),
|
||||||
|
const Rect.fromLTWH(200.0, 200.0, 200.0, 200.0));
|
||||||
|
}, variant: TargetPlatformVariant.all());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user