Search code examples
flutterlistviewcolorsflutter-listviewlisttile

Flutter: Why is my listTile color being overwritten by the container color?


I have a listTile builder that returns this listTile. The color of the listTile, white, is overwritten by its parent. How do I stop this?

return ListTile(
   key: Key(index.toString()),
   tileColor: Colors.white,
   title: Text(widget.userExercises[index].name),
   subtitle: Text("${widget.userExercises[index].reps} Reps"),
   trailing: Text("${widget.userExercises[index].sets} Sets"),
   onTap: () => widget.editFunction(widget.userExercises[index]),
);

However, when I run my app, the tileColor is overwritten by the parent Container's color.

return Container(
  alignment: Alignment.center,
  color: Colors.lightBlue,
  child: ExerciseTable(
    userExercises: todaysExercises,
    editFunction: _showEditDialog,
  ),
);

Resulting in the following:

The tiles with Bench Press should be white

Thank you! (and sorry for the image size I don't know how to change it)


Solution

  • ListTile paints its tileColor on a Material widget ancestor. When a colored Container is in between the ListTile and that ancestor you won't see the tileColor. To quote from here https://github.com/flutter/flutter/pull/86355/commits/9341a6b1d0d2852ee3c7eb413bbbdc9327f425c8 :

    /// Requires one of its ancestors to be a [Material] widget.
    /// One ancestor must be a [Material] widget and typically this is
    /// provided by the app's [Scaffold]. The [tileColor],
    /// [selectedTileColor], [focusColor], and [hoverColor] are not
    /// painted by the list tile itself but by the material widget
    /// ancestor. This generally has no effect. However, if an opaque
    /// widget, like `Container(color: Colors.white)`, is included in
    /// between the [ListTile] and its [Material] ancestor, then the
    /// opaque widget will obscure the material widget and its background
    /// [tileColor], etc. If this a problem, one can wrap a material
    /// widget around the list tile, e.g.:
    ///
    /// Container(
    ///   color: Colors.green,
    ///   child: Material(
    ///     child: ListTile(
    ///       title: const Text('ListTile with red background'),
    ///       tileColor: Colors.red,
    ///     ),
    ///   ),
    /// )
    

    See also this discussion: https://github.com/flutter/flutter/issues/83108