Skip to content

Commit 2ea9edc

Browse files
authored
Update KeepAlive.debugTypicalAncestorWidgetClass (flutter#133498)
1 parent b4953c3 commit 2ea9edc

File tree

4 files changed

+38
-11
lines changed

4 files changed

+38
-11
lines changed

packages/flutter/lib/src/cupertino/dialog.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1577,8 +1577,7 @@ class _ActionButtonParentDataWidget
15771577
}
15781578

15791579
@override
1580-
Type get debugTypicalAncestorWidgetClass =>
1581-
_CupertinoDialogActionsRenderWidget;
1580+
Type get debugTypicalAncestorWidgetClass => _CupertinoDialogActionsRenderWidget;
15821581
}
15831582

15841583
// ParentData applied to individual action buttons that report whether or not

packages/flutter/lib/src/widgets/framework.dart

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1592,15 +1592,19 @@ abstract class ParentDataWidget<T extends ParentData> extends ProxyWidget {
15921592
return renderObject.parentData is T;
15931593
}
15941594

1595-
/// The [RenderObjectWidget] that is typically used to set up the [ParentData]
1596-
/// that [applyParentData] will write to.
1595+
/// Describes the [RenderObjectWidget] that is typically used to set up the
1596+
/// [ParentData] that [applyParentData] will write to.
15971597
///
15981598
/// This is only used in error messages to tell users what widget typically
1599-
/// wraps this [ParentDataWidget].
1599+
/// wraps this [ParentDataWidget] through
1600+
/// [debugTypicalAncestorWidgetDescription].
16001601
///
16011602
/// ## Implementations
16021603
///
1603-
/// The returned type should be a subclass of `RenderObjectWidget`.
1604+
/// The returned Type should describe a subclass of `RenderObjectWidget`. If
1605+
/// more than one Type is supported, use
1606+
/// [debugTypicalAncestorWidgetDescription], which typically inserts this
1607+
/// value but can be overridden to describe more than one Type.
16041608
///
16051609
/// ```dart
16061610
/// @override
@@ -1612,6 +1616,16 @@ abstract class ParentDataWidget<T extends ParentData> extends ProxyWidget {
16121616
/// type is specialized), or specifying the upper bound (e.g. `Foo<Object?>`).
16131617
Type get debugTypicalAncestorWidgetClass;
16141618

1619+
/// Describes the [RenderObjectWidget] that is typically used to set up the
1620+
/// [ParentData] that [applyParentData] will write to.
1621+
///
1622+
/// This is only used in error messages to tell users what widget typically
1623+
/// wraps this [ParentDataWidget].
1624+
///
1625+
/// Returns [debugTypicalAncestorWidgetClass] by default as a String. This can
1626+
/// be overridden to describe more than one Type of valid parent.
1627+
String get debugTypicalAncestorWidgetDescription => '$debugTypicalAncestorWidgetClass';
1628+
16151629
Iterable<DiagnosticsNode> _debugDescribeIncorrectParentDataType({
16161630
required ParentData? parentData,
16171631
RenderObjectWidget? parentDataCreator,
@@ -1632,7 +1646,7 @@ abstract class ParentDataWidget<T extends ParentData> extends ProxyWidget {
16321646
),
16331647
ErrorHint(
16341648
'Usually, this means that the $runtimeType widget has the wrong ancestor RenderObjectWidget. '
1635-
'Typically, $runtimeType widgets are placed directly inside $debugTypicalAncestorWidgetClass widgets.',
1649+
'Typically, $runtimeType widgets are placed directly inside $debugTypicalAncestorWidgetDescription widgets.',
16361650
),
16371651
if (parentDataCreator != null)
16381652
ErrorHint(
@@ -6300,7 +6314,7 @@ abstract class RenderObjectElement extends Element {
63006314
ErrorSummary('Incorrect use of ParentDataWidget.'),
63016315
ErrorDescription('The following ParentDataWidgets are providing parent data to the same RenderObject:'),
63026316
for (final ParentDataElement<ParentData> ancestor in badAncestors)
6303-
ErrorDescription('- ${ancestor.widget} (typically placed directly inside a ${(ancestor.widget as ParentDataWidget<ParentData>).debugTypicalAncestorWidgetClass} widget)'),
6317+
ErrorDescription('- ${ancestor.widget} (typically placed directly inside a ${(ancestor.widget as ParentDataWidget<ParentData>).debugTypicalAncestorWidgetDescription} widget)'),
63046318
ErrorDescription('However, a RenderObject can only receive parent data from at most one ParentDataWidget.'),
63056319
ErrorHint('Usually, this indicates that at least one of the offending ParentDataWidgets listed above is not placed directly inside a compatible ancestor widget.'),
63066320
ErrorDescription('The ownership chain for the RenderObject that received the parent data was:\n ${debugGetCreatorChain(10)}'),

packages/flutter/lib/src/widgets/sliver.dart

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,8 +1311,8 @@ class _SliverOffstageElement extends SingleChildRenderObjectElement {
13111311
/// Mark a child as needing to stay alive even when it's in a lazy list that
13121312
/// would otherwise remove it.
13131313
///
1314-
/// This widget is for use in [SliverWithKeepAliveWidget]s, such as
1315-
/// [SliverGrid] or [SliverList].
1314+
/// This widget is for use in a [RenderAbstractViewport]s, such as
1315+
/// [Viewport] or [TwoDimensionalViewport].
13161316
///
13171317
/// This widget is rarely used directly. The [SliverChildBuilderDelegate] and
13181318
/// [SliverChildListDelegate] delegates, used with [SliverList] and
@@ -1322,6 +1322,9 @@ class _SliverOffstageElement extends SingleChildRenderObjectElement {
13221322
/// each child, causing [KeepAlive] widgets to be automatically added and
13231323
/// configured in response to [KeepAliveNotification]s.
13241324
///
1325+
/// The same `addAutomaticKeepAlives` feature is supported by the
1326+
/// [TwoDimensionalChildBuilderDelegate] and [TwoDimensionalChildListDelegate].
1327+
///
13251328
/// Therefore, to keep a widget alive, it is more common to use those
13261329
/// notifications than to directly deal with [KeepAlive] widgets.
13271330
///
@@ -1365,7 +1368,10 @@ class KeepAlive extends ParentDataWidget<KeepAliveParentDataMixin> {
13651368
bool debugCanApplyOutOfTurn() => keepAlive;
13661369

13671370
@override
1368-
Type get debugTypicalAncestorWidgetClass => SliverWithKeepAliveWidget;
1371+
Type get debugTypicalAncestorWidgetClass => throw FlutterError('Multiple Types are supported, use debugTypicalAncestorWidgetDescription.');
1372+
1373+
@override
1374+
String get debugTypicalAncestorWidgetDescription => 'SliverWithKeepAliveWidget or TwoDimensionalViewport';
13691375

13701376
@override
13711377
void debugFillProperties(DiagnosticPropertiesBuilder properties) {

packages/flutter/test/widgets/keep_alive_test.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ List<Widget> generateList(Widget child) {
4747
}
4848

4949
void main() {
50+
test('KeepAlive debugTypicalAncestorWidgetClass', () {
51+
final KeepAlive keepAlive = KeepAlive(keepAlive: false, child: Container());
52+
expect(
53+
keepAlive.debugTypicalAncestorWidgetDescription,
54+
'SliverWithKeepAliveWidget or TwoDimensionalViewport',
55+
);
56+
});
57+
5058
testWidgetsWithLeakTracking('KeepAlive with ListView with itemExtent', (WidgetTester tester) async {
5159
await tester.pumpWidget(
5260
Directionality(

0 commit comments

Comments
 (0)