【问题标题】:InkWell not showing ripple effectInkWell 没有显示涟漪效应
【发布时间】:2018-01-07 12:59:35
【问题描述】:

点击容器会触发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 中,但没有成功。

【问题讨论】:

    标签: flutter dart flutter-layout ripple-effect


    【解决方案1】:

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

    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 小部件进行飞溅。如果你在 Material 上面有什么东西,我们会在它下面飞溅,而你看不到它。

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

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

    --喜喜

    更新: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

    【讨论】:

    • 您可以将颜色放在Material 本身上,而忽略Container
    • 当 CopsOnRoad 发布他的答案时,我有点想通了。
    • @KoenVanLooveren 尝试 CopsOnRoad 答案。我没有编辑我的解决方案,因为 CopsOnRoad 的解决方案非常优雅
    • 这是我在重构后使用的:D 谢谢
    • 在我的情况下是容器形状,感谢解决方案
    【解决方案2】:

    截图:


    使用 Ink 小部件包裹在 InkWell 中。

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

    【讨论】:

    【解决方案3】:
    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,
                ),
              ),
            ),
          ),
        );
       }
      

    【讨论】:

      【解决方案4】:

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

      onTap : () {} 
      

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

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

      【讨论】:

      • 是的,我做到了,而且确实如此。检查来源:github.com/flutter/flutter/blob/… 在每个处理程序中,他们检查回调是否可用,否则不会发生任何事情。
      【解决方案5】:

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

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

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

      【讨论】:

        【解决方案6】:

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

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

        下面的代码可以工作。

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

        不要忘记在InkWell 中添加onTap: () {} 否则它会 也不显示涟漪效应。

        【讨论】:

          【解决方案7】:

          如果您想在任何小部件上添加 Ripple 效果

          1- 用 MaterialInkwell 包裹小部件。

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

          3- 从不color 设置为您希望它产生波纹的小部件。

             Material (
             color: const Color(0xcffFF8906),
             child: InkWell(
             ontap:() { },
             child: Container(
             color: Colors.transparent,
             height: 80,
             width: 80,
           )
          

          【讨论】:

            【解决方案8】:

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

            • InkWell 包裹你的Widget
            • Material 包裹InkWell
            • 无论如何将不透明度设置为 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");},
                ),
              )
              

            【讨论】:

            • 专业提示 --> 你也可以使用 Colors.transparent
            【解决方案9】:

            这对我有用:

            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. InkWell 包装在Material(color: Colors.white.withOpacity(0.0), ..)

            感谢这里的答案使这两点得到满足

            【讨论】:

              【解决方案10】:

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

              【讨论】:

                【解决方案11】:

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

                【讨论】:

                • 这就是诀窍。如果没有 onTap(),Ripple 将无法工作。谢谢大佬!
                【解决方案12】:

                我能够通过使用堆栈来解决我的问题。

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

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

                编辑:

                如果您使用convert the image to the right format,您仍然可以使用Ink.image

                【讨论】:

                  【解决方案13】:

                  设置 InkWell 容器的颜色

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

                  在使用 Material 父小部件创建 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: () {},
                        ),
                      ),
                    )
                  

                  【讨论】:

                    【解决方案14】:

                    现在使用 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),
                              ),
                            ),
                          ),
                        );
                      }
                    
                    

                    【讨论】:

                      【解决方案15】:
                      child: Material(
                      color: Colors.transparent
                      child: InkWell(
                        onTap: (){ print("this Ripple!";},
                        splashColor: Colors.greenAccent,
                        child: Container(
                          height:100.0,
                          color: Colors.white,
                        ),
                      ),
                      ),
                      

                      InkWell 之前添加Material 并将color 设置为Colors.transparent

                      【讨论】:

                        【解决方案16】:

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

                        1. onTap 不应为 null(或为空)。
                        2. InkWell 必须位于任何 Material 小部件中

                        【讨论】:

                          【解决方案17】:

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

                          【讨论】:

                            【解决方案18】:

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

                            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: () {}),
                                    ],
                                  ),
                                ),
                              )
                            

                            【讨论】:

                              【解决方案19】:

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

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

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

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

                              【讨论】:

                              【解决方案20】:

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

                                child: new Material(
                                  color: Colors.transparent
                                  child: new InkWell(
                                    onTap: (){},
                                    child: new Container(
                                      width: 100.0,
                                      height: 100.0,
                                      color: Colors.amber,
                                    ),
                                  ),
                                ),
                              

                              【讨论】:

                                猜你喜欢
                                • 2018-02-23
                                • 1970-01-01
                                • 2020-02-05
                                • 2016-04-25
                                • 2015-11-07
                                • 1970-01-01
                                • 1970-01-01
                                • 2018-11-13
                                • 2020-10-02
                                相关资源
                                最近更新 更多