ListTile throws exception when wrapped in a colored widget
ListTile throws an exception when it is wrapped in an intermediate widget with a non-transparent background color.
Summary
#
When a ListTile is wrapped in a widget with a non-transparent background color
(such as a Container or ColoredBox with a color specified) that sits between
the ListTile and its nearest Material ancestor, the framework now throws an
exception.
Background
#
ListTile paints its background color and ink splashes on the nearest Material
ancestor. When a widget with an opaque background color is placed between the
ListTile and its Material ancestor, it obscures these visual effects, making
them invisible to the user.
To prevent developers from accidentally introducing this bug and wondering why
the background or ink splash effects on the ListTile are not displaying, an
assert was introduced. This exception explicitly points out the issue during
development.
If your code has an intermediate colored widget between a ListTile and a
Material widget, you will see an error similar to this:
ListTile background color or ink splashes may be invisible.
The ListTile is wrapped in a Container that has a background color. Because
ListTile paints its background and ink splashes on the nearest Material
ancestor, this Container will hide those effects. To fix this, wrap the ListTile
in its own Material widget, or remove the background color from the intermediate
Container.
Migration guide
#
To fix the exception, follow the exception's hint and either remove the
background color from the intermediate widget, or wrap the ListTile in its own
Material widget.
Code before migration:
// The colored Container hides the ink splashes from the ListTile.
Material(
child: Container(
color: Colors.pink,
child: ListTile(
title: const Text('Title'),
onTap: () {},
),
),
)
Code after migration:
// Use a Material widget directly for the background color.
Material(
color: Colors.pink,
child: Container(
child: ListTile(
title: const Text('Title'),
onTap: () {},
),
),
)
Or you can wrap the ListTile in its own Material widget directly:
Container(
color: Colors.blue,
child: Material(
type: MaterialType.transparency,
child: ListTile(
title: const Text('Title'),
onTap: () {},
),
),
)
Timeline
#Landed in version: TBD In stable release: Not yet
References
#API documentation:
Relevant issues:
Relevant PRs:
Unless stated otherwise, the documentation on this site reflects Flutter 3.41.2. Page last updated on 2026-03-03. View source or report an issue.