|
| 1 | +--- |
| 2 | +title: Container with color optimization |
| 3 | +description: A container with a color and no other background decoration no |
| 4 | +longer builds the same child widgets. |
| 5 | +--- |
| 6 | + |
| 7 | +## Summary |
| 8 | + |
| 9 | +A new `ColoredBox` widget has been added to the framework, and the `Container` |
| 10 | +widget has been optimized to use it if a user specifies a `color` instead of a |
| 11 | +`decoration`. |
| 12 | + |
| 13 | +## Context |
| 14 | + |
| 15 | +It is very common to use the `Container` widget as follows: |
| 16 | + |
| 17 | +```dart |
| 18 | +return Container(color: Colors.red); |
| 19 | +``` |
| 20 | + |
| 21 | +Previously, this code would result in a widget heirarchy that used a |
| 22 | +`BoxDecoration` to actually paint the background color. The `BoxDecoration` |
| 23 | +widget covers many cases other than just painting a background color, and is |
| 24 | +not as efficient as the new `ColoredBox` widget, which only paints a background |
| 25 | +color. |
| 26 | + |
| 27 | +Widget tests that wanted to assert based on the color of a container in the |
| 28 | +widget tree would previously have to find the `BoxDecoration` to actually get |
| 29 | +the color of the container. Now, they are able to check the `color` property |
| 30 | +on the `Container` itself, unless a `BoxDecoration` was explicitly provided as |
| 31 | +the `decoration` property. It is still an error to supply both `color` and |
| 32 | +`decoration` to `Container`. |
| 33 | + |
| 34 | +## Migration guide |
| 35 | + |
| 36 | +Tests that assert on the color of a `Container` or that expected it to create a |
| 37 | +`BoxDecoration` need to be modified. |
| 38 | + |
| 39 | +Code before migration: |
| 40 | + |
| 41 | +<!-- skip --> |
| 42 | +```dart |
| 43 | +testWidgets('Container color', (WidgetTester tester) async { |
| 44 | + await tester.pumpWidget(Container(color: Colors.red)); |
| 45 | +
|
| 46 | + final Container container = tester.widgetList<Container>().first; |
| 47 | + expect(container.decoration.color, Colors.red); |
| 48 | + // Or, a test may have specifically looked for the BoxDecoration, e.g.: |
| 49 | + expect(find.byType(BoxDecoration), findsOneWidget); |
| 50 | +}); |
| 51 | +``` |
| 52 | + |
| 53 | +Code after migration: |
| 54 | + |
| 55 | +<!-- skip --> |
| 56 | +```dart |
| 57 | +testWidgets('Container color', (WidgetTester tester) async { |
| 58 | + await tester.pumpWidget(Container(color: Colors.red)); |
| 59 | +
|
| 60 | + final Container container = tester.widgetList<Container>().first; |
| 61 | + expect(container.color, Colors.red); |
| 62 | + // If your test needed to work directly with the BoxDecoration, it should |
| 63 | + // instead look for the ColoredBox, e.g.: |
| 64 | + expect(find.byType(BoxDecoration), findsNothing); |
| 65 | + expect(find.byType(ColoredBox), findsOneWidget); |
| 66 | +}); |
| 67 | +``` |
| 68 | + |
| 69 | +## Timeline |
| 70 | + |
| 71 | +This change was introduced in v1.15.4 |
| 72 | + |
| 73 | +## References |
| 74 | + |
| 75 | +API documentation: |
| 76 | +* [`Container`][] |
| 77 | +* [`ColoredBox`][] |
| 78 | +* [`BoxDecoration`][] |
| 79 | + |
| 80 | +Relevant issues: |
| 81 | +* [Issue 9672][] |
| 82 | +* [Issue 28753][] |
| 83 | + |
| 84 | +Relevant PRs: |
| 85 | +* [Colored box and container optimization #50979][] |
| 86 | + |
| 87 | +[`Container`]: {{site.api}}/flutter/widgets/Container-class.html |
| 88 | +[`ColoredBox`]: {{site.api}}/flutter/widgets/ColoredBox-class.html |
| 89 | +[`BoxDecoration`]: {{site.api}}/flutter/painting/BoxDecoration-class.html |
| 90 | +[Issue 9672]: {{site.github}}/flutter/flutter/issues/9672 |
| 91 | +[Issue 28753]: {{site.github}}/flutter/flutter/issues/28753 |
| 92 | +[Colored box and container optimization #50979]: {{site.github}}/flutter/flutter/pull/[link_to_actual_pr] |
0 commit comments