Flutter:Inkwell与Card不兼容

42

我试图在卡片小部件上实现inkWell包装,但它根本不起作用。 我将onTap留空,因为此类需要3个参数,我稍后填充以生成多个卡片。 我看不到什么阻止InkWell引起涟漪的问题,所以任何帮助都将不胜感激。

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,

      );



  }
10个回答

64

我最终通过在父级卡片小部件和子级墨水井小部件中指定相同的边框半径来使其工作。其他解决方案不会正确地呈现墨水井动画的圆角。以下方法完美地适用于我:

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

6
尝试在你的卡片(或InkWell)内添加一张图片,然后检查是否有效果。 :) - diegoveloper
@diegoveloper 将 Ink.image() 包装到您的图像中。 - Mayb3Not
这应该是被接受的答案!谢谢伙计。 - Anoop Thiruonam
这个答案应该被接受!完美! - SwiftiSwift
我已经寻找了一年,谢谢伙计。 - Muhammet
最好在Card内部使用clipBehavior: Clip.hardEdge,以避免重复编写borderRadius: BorderRadius.circular(8)的代码。这样无论Card的半径如何,它都能正确地裁剪InkWell的涟漪。 - undefined

54

解释:

“发生的情况是Material规范说明,涟漪实际上是材料上的墨水。所以当我们制造涟漪时,我们做的就是让材料小部件进行涟漪效果。如果你在材料上面放置了其他内容,我们会在其下方制造涟漪,而你看不到它。”

解决方法:

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,
                    )))
          ]);

5
这不会识别卡片组件中的手势。 - Ramesh-X

15
  • 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
            ),
          ),
        ),
      ),
    )
    

不必使用三次 borderRadius,你可以将整个 Card 包装在一个 ClipRRrect 中,然后只给它设置一次 borderRadius,但如果半径从 24 增加到 72,则剪辑效率可能不高。 - CopsOnRoad
谢谢!你帮我想通了! - Georgiy Chebotarev
@CopsOnRoad ClipRRect的一个不好的地方是,如果使用elevation:属性,它也会剪裁阴影。而第二个缺点是,即使你将剪裁区域设为圆形,可点击区域仍然保持正方形。 解决方案是,在一个卡片中保持shape: ...和半径,并添加clipBehavior: Clip.hardEdge。这样可以正确地剪裁图像和涟漪效果。 - undefined

13

好的,我是如何做到的就是把我的Inkwell放在卡片里面。 在树之前是这样的:

Inkwell -> Card -> Container。

Inkwell的涟漪效果在上述代码中不起作用,所以我做的是

Card -> Material -> Inkwell -> Container

让我在代码里展示一下

之前的代码

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

之后

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
      )
     ),
    ),
  ),
              

希望这可以帮到你! :) 如果有任何问题,请告诉我!


对于Material Widget集,将color: Colors.transparent设置为透明色,否则会干扰卡片的颜色。 - undefined
Card已经在底层使用了Material,所以在这里将额外的Material放入小部件树中是多余的。关键是按照确切的顺序放置'Card -> Inkwell',而不是反过来。 - undefined

9

最简单的解决方案是使用一个包含您的小部件的子容器Inkwell小部件。

重要的是,在InkWell小部件上,onTap属性不能为空!

示例

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'),
              ),
            ],
          ),
        ),
      ),

3
要在卡片上看到涟漪动画,请尝试将onTap:null更改为onTap:(){}

2

对于具有涟漪效果的tap属性部件,其onTap方法不应为null。请将onTap方法设为()=>null;

希望已解答!

2

我知道这是一篇旧帖子,对于那些面临相同问题的人,你需要做的是在你创建的自定义小部件上叠加InkWell,给Material应用程序一个透明的背景。

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"),
          ),
        ))
      ],
    ));

1

不使用卡片和墨水瓶,您可以将小部件内容放入raised button中,并使用onPressed代替on tap。然后,您可以指定自定义形状,涟漪将具有相同的形状。

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"),
  ),
),

0
为了在覆盖图像的卡片上获得Inkwell水波纹效果(溅开效果),您可以使用Ink.image类来实现。这个方法非常有效。
Card(
  child: Ink.image(
     image: AssetImage('images/dog.jpeg'),
     fit: BoxFit.contain,
     height: 100,
     child: InkWell(
        splashColor: Colors.green.withOpacity(.2),
        onTap: () {},
     ),
   ),
 )

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接