flutteruser-interfacegridviewmaterial-uiripple-effect

Flutter: How to make a ripple effect with InkWell over an image in a GridTile


I'm trying to use an InkWell to get a Ripple Effect on top of an image inside a GridTile when the user taps on the tile.

I believe the image itself is obscuring the ripple because when I remove the image, I see the ripple.

Below is the code for a single GridTile.

return InkWell(
  onTap: () => debugPrint(s.displayName),
  highlightColor: Colors.pinkAccent,
  splashColor: Colors.greenAccent,
  child: GridTile(
    footer: GridTileBar(
      title: Text(s.displayName),
      subtitle: Text(s.gameName),
      backgroundColor: Colors.black45,
      trailing: const Icon(
        Icons.launch,
        color: Colors.white,
      ),
    ),
    child: Image.network(
      // This is obscuring the InkWell ripple
      s.imageSrc,
      fit: BoxFit.cover,
    ),
  ),
);

I've tried moving the InkWell to different levels of the tree and using DecorationImage inside a Container, but none of these seem to work to reveal the ripple.

How can I get the ripple to appear on top of the tile/image?


Solution

  • I was able to get the Ripple Effect over the image by wrapping the widget tree with a Stack and adding a Material widget with an InkWell inside as follows:

    return Stack(
      children: [
        Positioned.fill(
          bottom: 0.0,
          child: GridTile(
            footer: GridTileBar(
              title: Text(s.displayName),
              subtitle: Text(s.gameName),
              backgroundColor: Colors.black45,
              trailing: const Icon(
                Icons.launch,
                color: Colors.white,
              ),
            ),
            child: Image.network(s.imageSrc, fit: BoxFit.cover),
          ),
        ),
    
        // This is the widget that achieves the ripple effect.
        Positioned.fill(
          child: Material(
            color: Colors.transparent,
            child: InkWell(
              splashColor: Colors.lightGreenAccent,
              onTap: () => _launchStream(s.displayName),
            ),
          ),
        ),
      ],
    );