InkWell ripple over top of image in GridTile in Flutter

Flutter

Flutter Problem Overview


I'm trying to use InkWell to get a ripple effect on top of an image inside of 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 new InkWell(
  onTap: () => debugPrint(s.displayName),
  highlightColor: Colors.pinkAccent,
  splashColor: Colors.greenAccent,
  child: new GridTile(
    footer: new GridTileBar(
      title: new Text(s.displayName),
      subtitle: new Text(s.gameName),
      backgroundColor: Colors.black45,
      trailing: new Icon(
        Icons.launch,
        color: Colors.white,
      ),
    ),
    child: new Image.network( //this is obscuring the InkWell ripple
      s.imageSrc,
      fit: BoxFit.cover,
    ),
   ),
 );

I've tried moving the InkWell to different levels of the hierarchy, 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?

Flutter Solutions


Solution 1 - Flutter

I was able to get a ripple to appear over the image by using a Stack and wrapping the InkWell in a Material widget.

return new Stack(children: <Widget>[
        new Positioned.fill(
          bottom: 0.0,
          child: new GridTile(
              footer: new GridTileBar(
                title: new Text(s.displayName),
                subtitle: new Text(s.gameName),
                backgroundColor: Colors.black45,
                trailing: new Icon(
                  Icons.launch,
                  color: Colors.white,
                ),
              ),
              child: new Image.network(s.imageSrc, fit: BoxFit.cover)),
        ),
        new Positioned.fill(
            child: new Material(
                color: Colors.transparent,
                child: new InkWell(
                  splashColor: Colors.lightGreenAccent,
                  onTap: () => _launchStream(s.displayName),
                ))),
      ]);

Solution 2 - Flutter

I think this would be a better way to show ripple effect over image.

Ink.image(
    image: AssetImage('sample.jpg'),
    fit: BoxFit.cover,
    child: InkWell(
        onTap: () {},
    ),
),

The root cause is that Flutter renders views in descending order. when we put our image as the child of InkWell, the effect is covered by that image.

Find out more references here:

The Ink widget

Create a Rounded Image Icon with Ripple Effect in Flutter

Solution 3 - Flutter

Using Stack we can bring Material and InkWell over the image. To stretch Material we are going to use Positioned.fill widget.

Stack(
  children: <Widget>[
    Image( ... ),
    Positioned.fill(
      child: Material(
        color: Colors.transparent,
        child: InkWell(
          onTap: () { ... },
        ),
      ),
    ),
  ],
);

DartPad | Gist

Screenshot

This screenshot is taken from given dartpad link.

InkWell ripple over the Image

Solution 4 - Flutter

We have created this simple Widget to paint an ink reaction on top of any given child.

class InkWrapper extends StatelessWidget {
  final Color splashColor;
  final Widget child;
  final VoidCallback onTap;

  InkWrapper({
    this.splashColor,
    @required this.child,
    @required this.onTap,
  });

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        child,
        Positioned.fill(
          child: Material(
            color: Colors.transparent,
            child: InkWell(
              splashColor: splashColor,
              onTap: onTap,
            ),
          ),
        ),
      ],
    );
  }
}

Solution 5 - Flutter

Screenshot:

enter image description here

SizedBox(
  height: 200,
  child: Ink(
    decoration: BoxDecoration(
      image: DecorationImage(
        image: ExactAssetImage("chocolate_image"),
        fit: BoxFit.cover,
      ),
    ),
    child: InkWell(
      onTap: () {},
      splashColor: Colors.brown.withOpacity(0.5),
    ),
  ),
)

Solution 6 - Flutter

Here is how I solved it :

Container(
              height: 200,
              width: 200,
              decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(15)),
              child: Stack(
                children: [
                  Center(child: Image.asset("images/1.png")),
                  Container(
                    height: 200,
                    width: 200,
                    child: FlatButton(
                      onPressed: () {
                        
                      },
                      child: Text(""),
                    ),
                  ),
                ],
              ),
            ),

Solution 7 - Flutter

wrap InkWell inside Material Widget

Material(   
  child : InkWell(          
      child : YourWidget     
  )      
)  

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionVINView Question on Stackoverflow
Solution 1 - FlutterVINView Answer on Stackoverflow
Solution 2 - FlutterJaden GuView Answer on Stackoverflow
Solution 3 - FlutterTheMisirView Answer on Stackoverflow
Solution 4 - FlutterMrLepageView Answer on Stackoverflow
Solution 5 - FlutterCopsOnRoadView Answer on Stackoverflow
Solution 6 - FlutterMuhammetView Answer on Stackoverflow
Solution 7 - Flutteruser13108629View Answer on Stackoverflow