3

I've searched high and low, but cannot find a way to change the background color on a ListTile, for example when it is tapped by the user.

Does anyone have a solution to what seems like a common use case?

Lord Null
  • 856
  • 1
  • 9
  • 20

3 Answers3

8

To change the background color of a ListTile, you can simply wrap it in a Container and change its color attribute. Afterwards you can change the color, when onTap of the ListTile is triggered.

Demo:

Demo Gif

Demo Source:

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: CustomTile()
        ),
      ),
    );
  }
}

class CustomTile extends StatefulWidget {
  @override
  CustomTileState createState() => CustomTileState();
}

class CustomTileState extends State<CustomTile> {
  Color color;

  @override
  void initState() {
    super.initState();

    color = Colors.transparent;
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: color,
      child: ListTile(
        title: Text('Title'),
        subtitle: Text('Subtitle'),
        onTap: () {
          setState(() {
            color = Colors.lightBlueAccent;
          });
        },
      ),
    );
  }
}
NiklasPor
  • 9,116
  • 1
  • 45
  • 47
  • 4
    I see...the ListTile has to be wrapped in another Widget like a Container (or Card). I wonder why the Flutter devs didn't just integrate this functionality directly into the ListTile and enable it's bg color to be changed without the wrapping...seems like a common use case. Thanks @anmol.majhail and Niklas. I didn't post any code because it wouldn't have helped in this instance. My code was a hot mess. – Lord Null Dec 07 '18 at 17:00
  • @pskink Yes I looked at InkWell. I like that it offers onTap, onDoubleTap and onLongPress handlers. Apart from that is there any advantage to using one approach over another, e.g. wrapping ListTiles in InkWell and not Container? – Lord Null Dec 08 '18 at 08:23
  • @LordNull see [ListTile#build](https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/material/list_tile.dart#L458) – pskink Dec 08 '18 at 08:50
  • I'm not quite sure what that is illustrating. Can you explain briefly pls? – Lord Null Dec 08 '18 at 09:07
  • @LordNull it simply says that `InkWell` is used internally by every `ListTile` item – pskink Dec 08 '18 at 09:09
  • If that's the case why is onDoubleTap callback not available in ListTile? (It seems to have onTap and onLongPress.) – Lord Null Dec 08 '18 at 09:21
  • @LordNull ask the guy who wrote `ListTile` why he did not add it (`onTapDown` is not handled as well – pskink Dec 08 '18 at 09:57
  • In most use cases `onTapDown` and `onDoubleTap` is not needed while using a `ListTile`. If we would add all listeners, provided by the `Inkwell`, we'd also had to add all of them to `RaisedButton` and literally every other button. With this solution we can keep the constructors short and clear. If extended support for **gestures** is needed, we can always wrap Widgets in an [InkWell](https://docs.flutter.io/flutter/material/InkWell-class.html) or [GestureDetector](https://docs.flutter.io/flutter/widgets/GestureDetector-class.html). – NiklasPor Dec 08 '18 at 10:30
  • Thanks really I didn't understand it before – Shady Mohamed Sherif Dec 26 '19 at 08:05
3

As You Haven't Describes your Use Case or shared any Code i have shared sample code that Change Listile Color onTap()

class Screen1 extends StatefulWidget {
  @override
  Screen1State createState() {
    return new Screen1State();
  }
}

class Screen1State extends State<Screen1> {
  bool _color;

  @override
  void initState() {
    super.initState();
    _color = true;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
      child: Card(
        color: _color ? Colors.deepOrangeAccent : Colors.purpleAccent,
        child: ListTile(
          onTap: () {
            setState(() {
              _color = !_color;
            });
          },
          title: Text(
            'Title',
            style: TextStyle(color: Colors.white),
          ),
          subtitle: Text(
            'Subtitle',
            style: TextStyle(color: Colors.white),
          ),
        ),
      ),
    ));
  }
}
anmol.majhail
  • 48,256
  • 14
  • 136
  • 105
0

If you just want a quick way to do it, without much code and customization, you can wrap it with RaisedButton like this :

RaisedButton(
  color: ...
  child: ListTile(
    color: Colors.transparent,
    ...
  )

)

You can also use many properties like elevation, highlight color, focus color and much more.

Bensal
  • 3,316
  • 1
  • 23
  • 35