diff --git a/dev/tracing_tests/test/timeline_test.dart b/dev/tracing_tests/test/timeline_test.dart index 92cb5bf11a..9b2df6d1f7 100644 --- a/dev/tracing_tests/test/timeline_test.dart +++ b/dev/tracing_tests/test/timeline_test.dart @@ -120,7 +120,7 @@ void main() { args = (events.where((TimelineEvent event) => event.json!['name'] == '$RenderCustomPaint').single.json!['args'] as Map).cast(); expect(args['creator'], startsWith('CustomPaint')); expect(args['creator'], contains('Placeholder')); - expect(args['foregroundPainter'], startsWith('_PlaceholderPainter#')); + expect(args['painter'], startsWith('_PlaceholderPainter#')); debugProfileLayoutsEnabled = false; debugProfilePaintsEnabled = true; @@ -133,7 +133,7 @@ void main() { args = (events.where((TimelineEvent event) => event.json!['name'] == '$RenderCustomPaint').single.json!['args'] as Map).cast(); expect(args['creator'], startsWith('CustomPaint')); expect(args['creator'], contains('Placeholder')); - expect(args['foregroundPainter'], startsWith('_PlaceholderPainter#')); + expect(args['painter'], startsWith('_PlaceholderPainter#')); debugProfilePaintsEnabled = false; }, skip: isBrowser); // [intended] uses dart:isolate and io. diff --git a/packages/flutter/lib/src/widgets/placeholder.dart b/packages/flutter/lib/src/widgets/placeholder.dart index ec6ee1176e..70fccf942a 100644 --- a/packages/flutter/lib/src/widgets/placeholder.dart +++ b/packages/flutter/lib/src/widgets/placeholder.dart @@ -59,6 +59,7 @@ class Placeholder extends StatelessWidget { this.strokeWidth = 2.0, this.fallbackWidth = 400.0, this.fallbackHeight = 400.0, + this.child }) : super(key: key); /// The color to draw the placeholder box. @@ -83,6 +84,10 @@ class Placeholder extends StatelessWidget { /// * [fallbackWidth], the same but horizontally. final double fallbackHeight; + /// The [child] contained by the placeholder box. + /// + /// Defaults to null. + final Widget? child; @override Widget build(BuildContext context) { return LimitedBox( @@ -90,10 +95,11 @@ class Placeholder extends StatelessWidget { maxHeight: fallbackHeight, child: CustomPaint( size: Size.infinite, - foregroundPainter: _PlaceholderPainter( + painter: _PlaceholderPainter( color: color, strokeWidth: strokeWidth, ), + child: child, ), ); } @@ -105,5 +111,6 @@ class Placeholder extends StatelessWidget { properties.add(DoubleProperty('strokeWidth', strokeWidth, defaultValue: 2.0)); properties.add(DoubleProperty('fallbackWidth', fallbackWidth, defaultValue: 400.0)); properties.add(DoubleProperty('fallbackHeight', fallbackHeight, defaultValue: 400.0)); + properties.add(DiagnosticsProperty('child', child, defaultValue: null)); } } diff --git a/packages/flutter/test/widgets/keep_alive_test.dart b/packages/flutter/test/widgets/keep_alive_test.dart index 2a3bdf30ea..9a819ea287 100644 --- a/packages/flutter/test/widgets/keep_alive_test.dart +++ b/packages/flutter/test/widgets/keep_alive_test.dart @@ -327,8 +327,7 @@ void main() { ' │ parentData: (can use size)\n' ' │ constraints: BoxConstraints(w=800.0, h=400.0)\n' ' │ size: Size(800.0, 400.0)\n' - ' │ painter: null\n' - ' │ foregroundPainter: _PlaceholderPainter#00000()\n' + ' │ painter: _PlaceholderPainter#00000()\n' ' │ preferredSize: Size(Infinity, Infinity)\n' ' │\n' ' ├─child with index 1: RenderLimitedBox#00000\n' // <----- no dashed line starts here @@ -342,8 +341,7 @@ void main() { ' │ parentData: (can use size)\n' ' │ constraints: BoxConstraints(w=800.0, h=400.0)\n' ' │ size: Size(800.0, 400.0)\n' - ' │ painter: null\n' - ' │ foregroundPainter: _PlaceholderPainter#00000()\n' + ' │ painter: _PlaceholderPainter#00000()\n' ' │ preferredSize: Size(Infinity, Infinity)\n' ' │\n' ' └─child with index 2: RenderLimitedBox#00000 NEEDS-PAINT\n' @@ -357,8 +355,7 @@ void main() { ' parentData: (can use size)\n' ' constraints: BoxConstraints(w=800.0, h=400.0)\n' ' size: Size(800.0, 400.0)\n' - ' painter: null\n' - ' foregroundPainter: _PlaceholderPainter#00000()\n' + ' painter: _PlaceholderPainter#00000()\n' ' preferredSize: Size(Infinity, Infinity)\n', )); const GlobalObjectKey<_LeafState>(0).currentState!.setKeepAlive(true); @@ -490,8 +487,7 @@ void main() { ' │ parentData: (can use size)\n' ' │ constraints: BoxConstraints(w=800.0, h=400.0)\n' ' │ size: Size(800.0, 400.0)\n' - ' │ painter: null\n' - ' │ foregroundPainter: _PlaceholderPainter#00000()\n' + ' │ painter: _PlaceholderPainter#00000()\n' ' │ preferredSize: Size(Infinity, Infinity)\n' ' │\n' ' ├─child with index 5: RenderLimitedBox#00000\n' // <----- this is index 5, not 0 @@ -505,8 +501,7 @@ void main() { ' │ parentData: (can use size)\n' ' │ constraints: BoxConstraints(w=800.0, h=400.0)\n' ' │ size: Size(800.0, 400.0)\n' - ' │ painter: null\n' - ' │ foregroundPainter: _PlaceholderPainter#00000()\n' + ' │ painter: _PlaceholderPainter#00000()\n' ' │ preferredSize: Size(Infinity, Infinity)\n' ' │\n' ' ├─child with index 6: RenderLimitedBox#00000\n' @@ -520,8 +515,7 @@ void main() { ' │ parentData: (can use size)\n' ' │ constraints: BoxConstraints(w=800.0, h=400.0)\n' ' │ size: Size(800.0, 400.0)\n' - ' │ painter: null\n' - ' │ foregroundPainter: _PlaceholderPainter#00000()\n' + ' │ painter: _PlaceholderPainter#00000()\n' ' │ preferredSize: Size(Infinity, Infinity)\n' ' │\n' ' ├─child with index 7: RenderLimitedBox#00000 NEEDS-PAINT\n' @@ -535,8 +529,7 @@ void main() { ' ╎ parentData: (can use size)\n' ' ╎ constraints: BoxConstraints(w=800.0, h=400.0)\n' ' ╎ size: Size(800.0, 400.0)\n' - ' ╎ painter: null\n' - ' ╎ foregroundPainter: _PlaceholderPainter#00000()\n' + ' ╎ painter: _PlaceholderPainter#00000()\n' ' ╎ preferredSize: Size(Infinity, Infinity)\n' ' ╎\n' ' ╎╌child with index 0 (kept alive but not laid out): RenderLimitedBox#00000\n' // <----- this one is index 0 and is marked as being kept alive but not laid out @@ -550,8 +543,7 @@ void main() { ' ╎ parentData: (can use size)\n' ' ╎ constraints: BoxConstraints(w=800.0, h=400.0)\n' ' ╎ size: Size(800.0, 400.0)\n' - ' ╎ painter: null\n' - ' ╎ foregroundPainter: _PlaceholderPainter#00000()\n' + ' ╎ painter: _PlaceholderPainter#00000()\n' ' ╎ preferredSize: Size(Infinity, Infinity)\n' ' ╎\n' // <----- dashed line ends here ' └╌child with index 3 (kept alive but not laid out): RenderLimitedBox#00000\n' @@ -565,8 +557,7 @@ void main() { ' parentData: (can use size)\n' ' constraints: BoxConstraints(w=800.0, h=400.0)\n' ' size: Size(800.0, 400.0)\n' - ' painter: null\n' - ' foregroundPainter: _PlaceholderPainter#00000()\n' + ' painter: _PlaceholderPainter#00000()\n' ' preferredSize: Size(Infinity, Infinity)\n', )); }, skip: kIsWeb); // https://github.com/flutter/flutter/issues/87876 diff --git a/packages/flutter/test/widgets/placeholder_test.dart b/packages/flutter/test/widgets/placeholder_test.dart index 625ad0a873..f0376e2fb6 100644 --- a/packages/flutter/test/widgets/placeholder_test.dart +++ b/packages/flutter/test/widgets/placeholder_test.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -34,4 +35,11 @@ void main() { await tester.pumpWidget(const Placeholder(strokeWidth: 10.0)); expect(tester.renderObject(find.byType(Placeholder)), paints..path(strokeWidth: 10.0)); }); + + testWidgets('Placeholder child widget', (WidgetTester tester) async { + await tester.pumpWidget(const Placeholder()); + expect(find.text('Label'), findsNothing); + await tester.pumpWidget(const MaterialApp(home: Placeholder(child: Text('Label')))); + expect(find.text('Label'), findsOneWidget); + }); }