169

点击容器会触发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但徒劳无功。

4

21 回答 21

262

我认为给容器添加颜色覆盖了墨水效果

https://api.flutter.dev/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,它对装饰做类似的事情。或者我们可以让 Material 本身进行装饰。现在它需要一种颜色,但我们可以将其扩展到整个装饰。不过,尚不清楚具有渐变的材质是否真的与材质规范兼容,所以我不确定我们是否应该这样做。

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

--hixie

更新:Hixie 去年合并了一个新的 Ink 解决方案。Ink 提供了一种在图像上飞溅的便捷方式。

  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

于 2017-07-31T23:38:35.670 回答
175

截屏:

在此处输入图像描述


使用Ink包裹在InkWell.

InkWell(
  onTap: () {}, // Handle your onTap 
  child: Ink(
    width: 200,
    height: 200,
    color: Colors.blue,
  ),
)
于 2018-10-08T08:11:22.273 回答
39
  1. InkWell 小部件必须有一个 Material 小部件作为祖先,否则它无法显示效果。例如:

    Material(
      child : InkWell(
        child : .....
    
  2. 您必须添加onTap方法才能看到实际效果

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

让我们来看看下面的一些例子,并尝试理解 InkWell 的实际概念。

  • 在下面的示例中,材料是带有 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,
            ),
          ),
        ),
      );
    }
    
  • 低于 exp。在所有页面中显示效果,因为中心从所有侧面创建边距。从顶部、左侧、右侧和底部居中对齐它的子小部件。

    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,
              ),
            ),
          ),
        ),
      );
     }
    
于 2019-10-09T12:54:43.290 回答
34

InkWell() 将永远不会显示涟漪效应,直到您添加

onTap : () {} 

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

InkWell 中的参数,因为它仅在您指定此参数时才开始监听您的点击。

于 2018-08-07T16:45:23.860 回答
15

我为我找到了这个解决方案。我认为它可以帮助你:

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

Color提供给 Material 小部件。它是小部件的默认颜色。splashColor您可以使用Inkwell 的属性调整波纹效果的颜色。

于 2020-06-29T07:00:48.387 回答
12

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

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

下面的代码将起作用。

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

不要忘记onTap: () {}InkWellelse 中添加一个它也不会显示涟漪效应。

于 2019-04-29T05:43:49.113 回答
8

如果你想在任何小部件上产生涟漪 效果:

1- 用MaterialInkwell包裹小部件。

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

3-永远不要颜色设置为您希望它波纹的小部件。

   Material (
   color: const Color(0xcffFF8906),
   child: InkWell(
   ontap:() { },
   child: Container(
   color: Colors.transparent,
   height: 80,
   width: 80,
 )
于 2020-12-01T01:44:38.470 回答
4

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

  • 包裹你WidgetInkWell
  • InkWell_Material
  • 无论如何设置不透明度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");},
      ),
    )
    
于 2019-10-25T10:18:17.020 回答
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), ..)

感谢这里的答案使这两点

于 2020-09-03T18:48:19.380 回答
2

我在尝试在 ListView 中创建 InkWell 的交替颜色时遇到了同样的问题。在这种特殊情况下,有一个简单的解决方案:将替代品包装在一个容器中,该容器使用大部分透明的色调/亮度变化——InkWell 触摸动画仍将在其下方可见。无需材料。请注意,在尝试使用材料解决此问题时还有其他问题 - 例如,它将覆盖您使用默认设置的 DefaultTextStyle(它安装 AnimatedDefaultTextStyle),这是一个巨大的痛苦。

于 2018-10-03T15:36:15.303 回答
2

我能够通过使用堆栈使我的情况正常工作。

Stack(
  children: [
    MyCustomWidget(), //              <--- Put this on bottom
    Material(
      color: Colors.transparent,
      child: InkWell(
        onTap: () {},
        child: Ink(
          width: 100,
          height: 100,
        ),
      ),
    ),
  ],
),

此页面上的其他答案对我不起作用的原因是我的自定义小部件隐藏了墨水效果并且我没有纯图像(所以我不能使用 Ink.image)。

编辑:

Ink.image如果您将图像转换为正确的格式,您仍然可以使用。

于 2021-01-19T04:26:08.900 回答
2

添加onTap:(){}监听器后,涟漪效果应该可以正常工作。BoxShadow()如果您在小部件中使用 with,它不起作用InkWell()

于 2020-08-18T04:29:31.510 回答
1
child: Material(
color: Colors.transparent
child: InkWell(
  onTap: (){ print("this Ripple!";},
  splashColor: Colors.greenAccent,
  child: Container(
    height:100.0,
    color: Colors.white,
  ),
),
),

Material在之前添加InkWell并设置colorColors.transparent.

于 2021-11-06T03:33:58.603 回答
1

现在使用 MaterialButton,在较新的版本中颤动


Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 16.0),
      child: MaterialButton(
        child: Text(
          labelText,
          style: TextStyle(fontSize: 22),
        ),
        onPressed: () {},
        color: backgroundColor,
        height: 45,
        minWidth: double.infinity,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.all(
            Radius.circular(16),
          ),
        ),
      ),
    );
  }

于 2021-06-24T19:49:42.513 回答
1

设置 InkWell 容器的颜色

放置在小部件内的任何子小Material部件都采用小部件中设置的颜色Material。因此,我们应该从 Material 的颜色属性本身设置颜色。您不能从任何父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: () {},
      ),
    ),
  )
于 2020-12-12T03:07:06.593 回答
1

为了处理涟漪效应,您应该使用以下规则:

  1. onTap不应该是null(或空的)。
  2. InkWell 必须在任何 Material Widget 中
于 2021-11-09T16:27:47.503 回答
0
  1. 创建一个支持 tap的小部件。
  2. 将其包装在 InkWell 小部件中以管理点击回调和波纹动画。

这是文档中提到的两点

例子:

InkWell(
        child: TextButton(
          onPressed: () {},
          child: Text('Tapped'),
          ),
        ),
      ),
于 2022-03-05T06:37:56.520 回答
0

在我的情况下,向 Material 添加透明颜色:

  child: new Material(
    color: Colors.transparent
    child: new InkWell(
      onTap: (){},
      child: new Container(
        width: 100.0,
        height: 100.0,
        color: Colors.amber,
      ),
    ),
  ),
于 2021-06-13T06:20:23.147 回答
0

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

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

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

onTap: (){ onTapItem(result); },
于 2020-11-03T11:32:58.323 回答
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: () {}),
        ],
      ),
    ),
  )
于 2020-06-15T20:25:21.920 回答
0

我遇到了一个类似的问题,将 Inkwell 添加到现有的复杂 Widget 中,Container 用颜色包装了 BoxDecoration。通过添加材料和墨水瓶的方式建议墨水瓶仍然被 BoxDecoration 遮挡,所以我只是让 BoxDecoration 的颜色稍微不透明,这样可以看到墨水瓶

于 2020-04-22T07:10:11.023 回答