Zeusox
Zeusox

Reputation: 8468

Flutter: Inkwell does not work with Card

I am trying to implement and inkWell wrap on a card widget, but it does not work at all. I am leaving on tap as null because this class takes 3 arguments that I populate later on to generate multiple cards. I cannot see what is going on that is preventing InkWell from rippling, so any help would be appreciated.

class FeedBackCardsImage extends StatelessWidget {
  final String imagePath;
  final String cardTitle;
  final String cardTag;

  FeedBackCardsImage({
    this.imagePath,
    this.cardTitle,
    this.cardTag,
  });

  @override
  Widget build(BuildContext context) {

      return InkWell(
          child: new Container(
            child: new Card(
              child: new Padding(
                padding: new EdgeInsets.all(15.0),
                child: new Column(
                  children: <Widget>[
                    new SizedBox(
                      height: 184.0,
                      child: new Stack(
                        children: <Widget>[
                          new Positioned.fill(
                            child: new Image.asset(
                              imagePath,
                              //package: destination.assetPackage,
                              fit: BoxFit.contain,
                            ),
                          ),
                        ],
                      ),
                    ),
                    new Padding(
                      padding: new EdgeInsets.all(
                        7.0,
                      ),
                      child: new Text(
                        cardTitle,
                        style: new TextStyle(
                            fontSize: 14.0,
                            fontWeight: FontWeight.w600,
                            color: Colors.black87),
                      ),
                    ),
                    new Padding(
                      padding: new EdgeInsets.all(
                        0.0,
                      ),
                      child: new Text(
                        cardTag,
                        style: new TextStyle(
                            fontSize: 12.0,
                            fontWeight: FontWeight.w400,
                            color: Colors.black54),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        onTap: null,

      );



  }

Upvotes: 45

Views: 31744

Answers (10)

John
John

Reputation: 2811

I finally got this to work by specifying the same border radius in both the parent card widget and the child inkwell widget. The other solutions don't correctly render rounded corners for the ink well animation. The below worked perfectly for me:

Card(
  elevation: 2,
  shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.circular(8),
  ),
  child: InkWell(
    borderRadius: BorderRadius.circular(8),
    onTap: (){},
    child: Container(
      height: 58,
    ),
  ),
);

Upvotes: 74

CopsOnRoad
CopsOnRoad

Reputation: 268404

  • Rounded Card (without image):

    enter image description here

    final borderRadius = BorderRadius.circular(24);
    
    Card(
      color: Colors.blue, // Backgrond color
      shape: RoundedRectangleBorder(borderRadius: borderRadius),
      child: InkWell(
        borderRadius: borderRadius,
        splashColor: Colors.red, // Splash color
        onTap: () {},
        child: Ink(width: 100, height: 100), 
      ),
    )
    
  • Rounded Card (with image):

    enter image description here

    final borderRadius = BorderRadius.circular(24);
    
    Card(
      shape: RoundedRectangleBorder(borderRadius: borderRadius),
      child: InkWell(
        borderRadius: borderRadius,
        splashColor: Colors.brown.withOpacity(0.7), // Splash color
        onTap: () {},
        child: Ink(
          width: 100,
          height: 100,
          decoration: BoxDecoration(
            borderRadius: borderRadius,
            image: DecorationImage(
              fit: BoxFit.cover,
              image: AssetImage('assets/chocolate_image.png'), // Background image
            ),
          ),
        ),
      ),
    )
    

Upvotes: 19

Sandz
Sandz

Reputation: 109

To get the Inkwell ripple effect (splash) on a card that has an image over it, you can use Ink.image class for this..This works well..

Card(
  child: Ink.image(
     image: AssetImage('images/dog.jpeg'),
     fit: BoxFit.contain,
     height: 100,
     child: InkWell(
        splashColor: Colors.green.withOpacity(.2),
        onTap: () {},
     ),
   ),
 )

Upvotes: 0

supamunkey
supamunkey

Reputation: 971

The simplest solution is to have an Inkwell widget with a child Container that contains your widget.

The important part here is that your onTap property on the InkWell widget cannot be null!

Example:

Card(
    child: InkWell(
        onTap: () {},
        child: Container(
          width: double.infinity,
          padding: EdgeInsets.all(20),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              icon,
              Padding(
                padding: const EdgeInsets.only(top: 8.0),
                child: Text('I'm a card Widget'),
              ),
            ],
          ),
        ),
      ),

Upvotes: 9

emmanuel kofi
emmanuel kofi

Reputation: 141

i know that this is an old post, for those who are facing the same problem , what you need to do is to stack the InkWell on top of the Custom Widget you have created , give the Material app a transparent background

Stack( children: <Widget>[
       YourWidget(),//            
        Container(         
          width: width,// full width
          height: width,// full height of the container the stack is in
            child: Material(
              // animationDuration: Duration(milliseconds:800),
          color: Colors.transparent,
          child: InkWell(
            onTap: (){
               Scaffold.of(context).showSnackBar(SnackBar(
      content: Text('Tap'),
    ));
            },
            highlightColor:  Colors.red,
            hoverColor: Colors.red,
            focusColor: Colors.red,
            child: Text("wow"),
          ),
        ))
      ],
    ));

Upvotes: 2

Maz341
Maz341

Reputation: 2484

Okay so how I did it was I just put my Inkwell inside the card. Before the tree was like

Inkwell -> Card -> Container.

Inkwell Ripple effect didn't work on the above one, so I did was

Card -> Material -> Inkwell -> Container

Let me show in code

Before

Card(
     margin: EdgeInsets.all(10.0),
     shape: RoundedRectangleBorder(
       borderRadius: BorderRadius.circular(10.0),
     ),
    child: Container(
     // My design code here
    )
)

After

Card(
  margin: EdgeInsets.all(10.0),
  shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.circular(10.0),
  ),
  child: Material(
    child: InkWell(
      splashColor: Colors.orange,
      onTap: (){
        print('Tapped!');
      },
      child: Container(
        // My design code here
      )
     ),
    ),
  ),
              

I hope this helps! :) Let me know if any questions!

Upvotes: 13

Bar Tzadok
Bar Tzadok

Reputation: 516

instead of using card and inkwell you can put your widget content in a raised button and use the onPressed instead of the on tap. then you can specify a costume shape and the ripple will have the same shape.

RaisedButton(
  elevation: 20,
  padding: EdgeInsets.all(0),
  onPressed: (){},
  shape: ContinuousRectangleBorder(
    borderRadius: BorderRadius.circular(100),
  ),
  color: Colors.red,
  child: Container(
    alignment: Alignment.topCenter, //raised button aligns to center automaticaly so you can use alignment so the widget will be aligned the way you want
    margin: EdgeInsets.only(top: 16),
    child: Text("cool"),
  ),
),

Upvotes: 1

Danylo
Danylo

Reputation: 5410

To see ripple animation on card try to change onTap: null to onTap: () {}

Upvotes: 2

diegoveloper
diegoveloper

Reputation: 103551

Explanation :

"What's going on is that the Material spec says that the splashes are actually ink on the Material. So when we splash, what we do is we literally have the Material widget do the splash. If you have something on top of the Material, we splash under it, and you can't see it."

Workaround :

return Stack(children: <Widget>[
            new Card(
              child: new Padding(
                padding: new EdgeInsets.all(15.0),
                child: new Column(
                  children: <Widget>[
                    new SizedBox(
                      height: 184.0,
                      child: new Stack(
                        children: <Widget>[
                          new Positioned.fill(
                            child: new Image.asset(
                              imagePath,
                              //package: destination.assetPackage,
                              fit: BoxFit.contain,
                            ),
                          ),
                        ],
                      ),
                    ),
                    new Padding(
                      padding: new EdgeInsets.all(
                        7.0,
                      ),
                      child: new Text(
                        cardTitle,
                        style: new TextStyle(
                            fontSize: 14.0,
                            fontWeight: FontWeight.w600,
                            color: Colors.black87),
                      ),
                    ),
                    new Padding(
                      padding: new EdgeInsets.all(
                        0.0,
                      ),
                      child: new Text(
                        cardTag,
                        style: new TextStyle(
                            fontSize: 12.0,
                            fontWeight: FontWeight.w400,
                            color: Colors.black54),
                      ),
                    ),
                  ],
                ),
              ),
            ),
            new Positioned.fill(
                child: new Material(
                    color: Colors.transparent,
                    child: new InkWell(
                      onTap: () => null,
                    )))
          ]);

Upvotes: 55

ShrJamal
ShrJamal

Reputation: 353

For widget that have tap property to ripple, it shouldn't have a null on onTap method. Give the onTap something like ()=>null; Hope Answered!

Upvotes: 2

Related Questions