InkWell和GestureDetector,如何使它们工作?

时间:2017-11-15 01:33:18

标签: flutter

我想使用GestureDetector进行onTapDown回调,但也有一个漂亮的InkWell泼溅效果。

是否可以将这两者结合使用?

3 个答案:

答案 0 :(得分:6)

如果您想无条件地处理没有gesture disambiguation的指针向下事件,您可以使InkWell成为监听器的子级,并设置onPointerDown处理程序。

例如:

new Listener(
  onPointerDown: (e) { print('onPointerDown'); },
  child: new InkWell(
    child: new Text('Tap me'),
    onTap: () { print('onTap'); }
  ),
),

向InkWell添加onTapDown处理程序可能是有意义的。

答案 1 :(得分:3)

您可以将HitTestBehavior传递给GestureDetector以使其成为"非阻止"通过将值设置为"半透明"

或者您也可以使用Material.of(context)

自行触发

答案 2 :(得分:0)

InkWell在引擎盖下使用GestureDetector:

https://github.com/flutter/flutter/blob/79b5e5bc8af7d9df3374dfe6141653848d1c03ac/packages/flutter/lib/src/material/ink_well.dart#L560

如果InkWell-Widget是GestureDetector不能正常工作的原因,它将其内部GestureDetector的行为设置为“ HitTestBehavior.opaque”。这样可以防止在父窗口小部件上发生“事件冒泡” /事件捕获(如果我的理解是正确的话)。而且因为“行为”是最终的,所以我们不能自己更改/修复它。

https://github.com/flutter/flutter/blob/79b5e5bc8af7d9df3374dfe6141653848d1c03ac/packages/flutter/lib/src/material/ink_well.dart#L566

正如我在上面的评论中提到的,我将InkWell封装在一个小部件(也可以处理其他内容)中,并提供了一种向其中传递回调的方法,该回调在所需事件上执行。

这是我的示例解决方案

import 'package:flutter/material.dart';

class CardPreview extends StatefulWidget {   

  final dynamic data;   
  final VoidCallback onTap;

  const CardPreview(this.data, this.onTap);

  CardPreview._(this.data, this.onTap);

  factory CardPreview.fromData(dynamic data, VoidCallback onTap) {
    return new CardPreview(data, onTap);
  }

  CardPreview createState() => new CardPreview(this.data, this.onTap);
}

class CardPreviewState extends State<CardPreview> {   
  final dynamic data;   
  final VoidCallback onTap;

  CardPreviewState(this.data, this.onTap);

  Widget buildCard() {
    return Material(
      color: Colors.transparent,
      child: Ink(
        child: InkWell(
          child: null,
          onTap: () {
            if (this.onTap == null) {
              return;
            }

            this.onTap();
          },
        ),
      ),
    );  
 }

  @override   
  Widget build(BuildContext context) {
    return Container(
      child: buildCard(),
    );   
  } 
}