InkWell不显示涟漪效应


104

轻敲容器会触发onTap()处理程序,但不会显示任何墨水飞溅效果。

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Center(
        child: new InkWell(
          onTap: (){print("tapped");},
          child: new Container(
            width: 100.0,
            height: 100.0,
            color: Colors.orange,
          ),
        ),
      ),
    );
  }
}

我试图把InkWell里面的东西也Container一样,但徒劳无功。

Answers:


162

我认为向容器中添加颜色可以覆盖墨水效果

https://docs.flutter.io/flutter/material/InkWell/InkWell.html

此代码似乎有效

  body: new Center(
    child: new Container(
      child: new Material(
        child: new InkWell(
          onTap: (){print("tapped");},
          child: new Container(
            width: 100.0,
            height: 100.0,
          ),
        ),
        color: Colors.transparent,
      ),
      color: Colors.orange,
    ),
  ),

只需单击中间的正方形。

编辑:我发现了错误报告。https://github.com/flutter/flutter/issues/3782

这实际上是预期的,尽管我们应该更新文档以使其更加清晰。

发生的情况是,“材料”规范指出,飞溅实际上是材料上的墨水。因此,当我们进行飞溅时,我们要做的是从字面上让Material部件进行飞溅。如果您在材料上方有东西,我们会在它下面飞溅,您将看不到它。

我想添加一个“ MaterialImage”小部件,该小部件在概念上也将其图像打印到“材质”中,以便随后的喷溅会覆盖该图像。我们可以有一个MaterialDecoration,它对装饰做类似的事情。或者我们可以让材料本身进行装饰。现在它需要一种颜色,但是我们可以将其扩展到采用整个装饰。不过,尚不清楚具有渐变材质是否真的符合材质规范,所以我不确定是否应该这样做。

在短期内,如果您只需要一种解决方法,则可以将“材质”放在容器的顶部,并将材质设置为使用“透明”类型,然后将墨水很好地放入其中。

--hixie

更新:Hixie去年合并了新的墨水解决方案。墨水提供了一种方便的方式来覆盖图像。

  testWidgets('Does the Ink widget render anything', (WidgetTester tester) async {
    await tester.pumpWidget(
      new Material(
        child: new Center(
          child: new Ink(
            color: Colors.blue,
            width: 200.0,
            height: 200.0,
            child: new InkWell(
              splashColor: Colors.green,
              onTap: () { },
            ),
          ),
        ),
      ),
    );


Material(
  color: Colors.grey[800],
  child: Center(
    child: Ink.image(
      image: AssetImage('cat.jpeg'),
      fit: BoxFit.cover,
      width: 300.0,
      height: 200.0,
      child: InkWell(
        onTap: () { /* ... */ },
        child: Align(
          alignment: Alignment.topLeft,
          child: Padding(
            padding: const EdgeInsets.all(10.0),
            child: Text('KITTEN', style: TextStyle(fontWeight: FontWeight.w900, color: Colors.white)),
          ),
        )
      ),
    ),
  ),
)

请注意:我没有测试新的Ink Widget。我处理了来自ink_paint_test.dart和Ink类文档的代码

https://github.com/Hixie/flutter/blob/1f6531984984f52328e66c0cd500a8d517964564/packages/flutter/test/material/ink_paint_test.dart

https://github.com/flutter/flutter/pull/13900

https://api.flutter.dev/flutter/material/Ink-class.html


2
您可以将颜色Material本身放在上面,而忽略掉Container
Herohtar

1
当CopsOnRoad发布他的答案时,我有点想。
user1462442'2

1
@KoenVanLooveren尝试CopsOnRoad答案。我没有编辑我的解决方案,因为CopsOnRoad的解决方案非常优雅
user1462442 '19

那就是我在重构后使用的:D谢谢
Koen Van Looveren

在我的情况下是容器形状,感谢解决方案
Mohammad Ersan

115

输出:

在此处输入图片说明


只需使用Ink包装在中的小部件即可InkWell

InkWell(
  onTap: () {}, // needed
  child: Ink( // use Ink
    width: 200,
    height: 200,
    color: Colors.blue,
  ),
)

消息来源确认了步骤3:github.com/flutter/flutter/blob / ...在每个处理程序中,他们检查回调是否可用,否则什么也没有发生。
Nightking

@CopsOnRoad,请问您在这里有一个与颤振相关的问题:stackoverflow.com/questions/60539378/…
Istiaque Ahmed'3

如果用完整的代码表示您给出的示例,则为是。我发现这是解决方案> stackoverflow.com/a/58556613/12140067
Chris

@Chris我认为您可能会受到Theme'或Material'的干扰,因为此代码会整天工作。
CopsOnRoad

25

除非您添加InkWell(),否则永远不会显示波纹效果。

onTap : () {} 

或任何回调,例如onDoubleTap,onLongPress等。

InkWell内部的参数,因为只有当您指定此参数时,它才会开始监听您的拍子。


是的,我做到了,这是真的。检查源:github.com/flutter/flutter/blob/…在每个处理程序中,他们检查回调是否可用,否则什么也没有发生。
Nightking

21
  1. InkWell小部件必须具有“材质”小部件作为祖先,否则它将无法显示效果。例如:

    Material(
      child : InkWell(
        child : .....
    
  2. 您必须添加onTap方法以查看实际效果,例如

     Buttons {RaisedButton,FlatButton etc}.
     e.g -> Material(
                 child : InkWell(
                         onTap : (){}
                         child : .....
    

让我们进入要点,请看下面的一些示例,并尝试了解InkWell的实际概念。

  • 在下面的示例中,Material是具有onTap的InkWell的父级,但仍无法正常工作。请尝试了解它的概念。您应该为容器或其他小部件提供一些边距以显示效果。实际上,下面的代码可以正常工作,但是我们看不到,因为我们没有提供任何边距或对齐方式,因此没有空间显示效果。

    Widget build(BuildContext context) {
      return Center(
        child: Material(
          child: new InkWell(
            onTap: () {
              print("tapped");
            },
            child: new Container(
              width: 100.0,
              height: 100.0,
              color: Colors.orange,
            ),  
          ),
        ),
      );
    }
    
  • 下例显示了InkWell效果,因为我们提供了{margin}空间。

    Widget build(BuildContext context) {
      return Center(
        child: Material(
          child: new InkWell(
            onTap: () {
              print("tapped");
            },
            child: new Container(
              margin: EdgeInsets.only(top: 100.0),
              width: 100.0,
              height: 100.0,
              color: Colors.orange,
            ),
          ),
        ),
      );
    }
    
  • 低于实验值 在所有页面上显示效果,因为居中位置从各个侧面都会产生空白。将其子控件从顶部,左侧,右侧和底部居中对齐。

    Widget build(BuildContext context) {
      return Center(
        child: Material(
          child: new InkWell(
            onTap: () {
              print("tapped");
            },
            child: Center(
              child: new Container(
                width: 100.0,
                height: 100.0,
                color: Colors.orange,
              ),
            ),
          ),
        ),
      );
     }
    

10

更好的方法是使用Ink小部件而不是其他任何小部件。

color您可以在Ink小部件本身中定义它,而不是在内部定义容器。

下面的代码将起作用。

Ink(
  color: Colors.orange,
  child: InkWell(
    child: Container(
      width: 100,
      height: 100,
    ),
    onTap: () {},
  ),
)

不要忘了onTap: () {}InkWell其他地方添加a ,它也不会显示涟漪效应。


7

我已经找到了解决方案。我认为它可以帮助您:

Material(
      color: Theme.of(context).primaryColor,
      child: InkWell(
        splashColor: Theme.of(context).primaryColorLight,
        child: Container(
          height: 100,
        ),
        onTap: () {},
      ),
    )

Color被赋予Material小部件。它是窗口小部件的默认颜色。您可以使用splashColorInkwell的属性调整波纹效果的颜色。


3

这是我发现并始终使用它的最佳方法。你可以尝试一下。

  • 包装你WidgetInkWell
  • InkWellMaterial
  • 无论如何,将不透明度设置为0%。例如:color: Colors.white.withOpacity(0.0),

    Material(
      color: Colors.white.withOpacity(0.0),
      child: InkWell(
        child: Container(width: 100, height: 100),
        onTap: (){print("Wow! Ripple");},
      ),
    )
    

3

这为我工作:

Material(
    color: Colors.white.withOpacity(0.0),
    child: InkWell(
      splashColor: Colors.orange,
      child: Text('Hello'), // actually here it's a Container wrapping an image
      onTap: () {
        print('Click');
      },
    ));

在这里尝试了许多答案之后,它是以下各项的组合:

  1. 设置 splashColor
  2. 包装InkWellMaterial(color: Colors.white.withOpacity(0.0), ..)

多亏了这里的答案,使这两点


2

我在尝试在ListView中创建InkWell的交替颜色时遇到了同样的问题。在这种情况下,有一个简单的解决方案:将替代项包装在使用几乎透明的色调/亮度更改的Container中-InkWell触摸动画在其下方仍然可见。不需要材料。请注意,尝试使用Materal解决此问题时还存在其他问题-例如,它将覆盖您使用的DefaultTextStyle和默认值(它将安装AnimatedDefaultTextStyle),这是一个很大的麻烦。


1

添加onTap:(){}侦听器后,波纹效果应该可以正常工作。如果BoxShadow()InkWell()窗口小部件中使用with,它将不起作用。


那是诀窍。没有onTap(),纹波将无法工作。谢啦!
Hardik Joshi

1

设置InkWell容器的颜色

放置在Material窗口小部件内的所有子窗口小部件都采用窗口小部件中设置的颜色Material。因此,我们应该从Material的color属性本身设置颜色。您不能从任何父Container窗口小部件设置它。

InkWell使用Material父窗口小部件进行创建时要注意的另一重要事项是,您应该从“材质”属性本身设置颜色。您无法从中进行设置Container

因此,我们修复InkWell效果和容器颜色的代码如下所示:

Container(
    margin: EdgeInsets.all(12),
    height: 50.0,
    width: 100.0,
    decoration: BoxDecoration(boxShadow: [
      BoxShadow(
          color: Colors.grey, blurRadius: 4, offset: Offset(0, 2))
    ]),
    child: Material(
      color: Colors.blue,
      child: InkWell(
        child: Center(
            child: Text("My Chip",
                style: Theme.of(context).textTheme.body1)),
        onTap: () {},
      ),
    ),
  )

0

我遇到了类似的问题,即向带有容器的包装有颜色的BoxDecoration的现有复杂Widget中添加墨水池。通过添加Material和Inkwell的方式表明,BoxDecoration仍然遮盖了Inkwell,所以我只是使BoxDecoration的颜色略微不透明,从而可以看到Inkwell


0

圆形小部件的解决方案如下所示:

Material(
    color: Colors.transparent,
    child: Container(
      alignment: Alignment.center,
      height: 100,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          IconButton(
              enableFeedback: true,
              iconSize: 40,
              icon: Icon(
                Icons.skip_previous,
                color: Colors.white,
                size: 40,
              ),
              onPressed: () {}),
          IconButton(
            iconSize: 100,
            enableFeedback: true,
            splashColor: Colors.grey,
            icon: Icon(Icons.play_circle_filled, color: Colors.white, size: 100),
            padding: EdgeInsets.all(0),
            onPressed: () {},
          ),
          IconButton(
              enableFeedback: true,
              iconSize: 40,
              icon: Icon(
                Icons.skip_next,
                color: Colors.white,
                size: 40,
              ),
              onPressed: () {}),
        ],
      ),
    ),
  )

0

对我来说,这是另一个问题。当我将onTap函数作为我的小部件的参数定义如下时,InkWell不会显示波纹效应。

Function(Result) onTapItem;
...
onTap: onTapItem(result),

我不知道有什么区别,但是下一个代码运行良好。

onTap: (){ onTapItem(result); },

0

如果要在任何小部件上使用波纹 效果,只需:

1-用MaterialInkwell包装小部件。

2-从Material设置小部件的颜色。

3-切勿颜色设置为要使其波纹的小部件。

   Material (
   color: const Color(0xcffFF8906),
   child: InkWell(
   ontap:() { },
   child: Container(
   color: Colors.transparent,
   height: 80,
   width: 80,
 )
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.