Dart 来自GestureDetector()的OnTappdown和其他回调被延迟

Dart 来自GestureDetector()的OnTappdown和其他回调被延迟,dart,flutter,Dart,Flutter,我目前正在使用gesturedector()创建一个带有AnimatedContainer()的自定义按钮 目标是在用户按下并释放按钮后,获得某种动画效果,如比例、颜色、阴影等 我现在的问题是onTapDown()回调延迟。可能是因为该按钮实际上是导致延迟的SliverList中的一个项目。但是,如果我在不滚动的情况下点击GestureDetector,则需要几百毫秒才能触发onTapDown回调。为什么? 我确实理解,对于列表中的对象,flatter和基本上任何其他UI框架都需要某种延迟触摸。

我目前正在使用
gesturedector()
创建一个带有
AnimatedContainer()的自定义按钮

目标是在用户按下并释放按钮后,获得某种动画效果,如比例、颜色、阴影等

我现在的问题是
onTapDown()
回调延迟。可能是因为该按钮实际上是导致延迟的
SliverList
中的一个项目。但是,如果我在不滚动的情况下点击GestureDetector,则需要几百毫秒才能触发
onTapDown
回调。为什么?

我确实理解,对于列表中的对象,flatter和基本上任何其他UI框架都需要某种延迟触摸。它必须确定用户想要滚动或按下按钮的原因

但你有什么想法,我可以显示一个漂亮的比例动画一旦用户按下这个容器

这是包含
RecipeMetaItem
滑动列表(然后对触摸输入做出反应)

下面是
RecipeMetaItem()


类RecipeMetItem扩展StatefulWidget{
最终双倍高度;
最终元项目元项目;
const RecipeMetaItem({Key-Key,this.metaItem,this.height=200}):super(Key:Key);
@凌驾
RecipeMetItemState createState(){
返回新的RecipeMetaItemState();
}
}
类RecipeMetItemState扩展了状态{
双偏置;
@凌驾
void initState(){
super.initState();
偏移量=0.0;
}
@凌驾
小部件构建(构建上下文){
返回填充(
填充:仅限常量边集(左:10.0,右:10.0,下:20.0),
儿童:手势检测器(
onTapDown:(详细信息){
设置状态(){
偏移量=-10;
});
},
onTapUp:(详细信息){
设置状态(){
偏移量=0;
});
},
子:动画容器(
持续时间:持续时间(毫秒:60),
曲线:Curves.easeOut,
变换:矩阵4.平移值(0,偏移量,0),
子:列(
儿童:[
容器(
高度:widget.height,
装饰:新盒子装饰(
boxShadow:[
箱形阴影(
颜色:颜色。黑色。带有Alpha(40),
半径:12.5,
扩展半径:0.0,
)
],
borderRadius:borderRadius.all(半径圆形(10)),
),
孩子:ClipRRect(
borderRadius:borderRadius.all(半径圆形(10)),
子:堆栈(
儿童:[
CachedNetworkImage(
适合:BoxFit.cover,
imageUrl:widget.metaItem.imageUrl,
fadeInDuration:持续时间(毫秒:50),
errorWidget:(上下文、url、错误)=>新图标(Icons.error),
),
],
),
),
),
填充物(
填充:仅限常量边集(顶部:8.0,左侧:4.0,右侧:4.0),
孩子:排(
儿童:[
扩大(
子:文本(
widget.metaItem.title,
textAlign:textAlign.left,
样式:TextStyle(fontWeight:fontWeight.w700,fontSize:17.0),
),
),
],
),
)
],
),
),
),
);
}
}

谢谢

不确定你是否解决了这个问题,但我在S.O.上发现了一个类似的问题,我认为同样的解决方案可能适用于你

尝试将手势检测器切换到侦听器并替换:

onTapDown: (details) {
  setState(() {
    offset = -10;
  });
},
onTapUp: (details) {
  setState(() {
    offset = 0;
  });
},
与:


希望这能解决问题,在这种情况下,问题将是手势检测器,而不是子部件。

然而,我刚刚注意到,监听器没有用于触摸屏的“onPointerCancel”功能。所以,虽然它有助于提高动画的速度,但它引入了另一个问题……我将尝试进一步研究它。如果您找到了更好的解决方案,请告诉我!

class RecipeMetaItem extends StatefulWidget {
  final double height;
  final MetaItem metaItem;

  const RecipeMetaItem({Key key, this.metaItem, this.height = 200}) : super(key: key);

  @override
  RecipeMetaItemState createState() {
    return new RecipeMetaItemState();
  }
}

class RecipeMetaItemState extends State<RecipeMetaItem> {
  double offset;


  @override
  void initState() {
    super.initState();
    offset = 0.0;
  }

  @override
  Widget build(BuildContext context) {

    return Padding(
      padding: const EdgeInsets.only(left: 10.0, right: 10.0, bottom: 20.0),
      child: GestureDetector(
        onTapDown: (details) {
          setState(() {
            offset = -10;
          });
        },
        onTapUp: (details) {
          setState(() {
            offset = 0;
          });
        },
        child: AnimatedContainer(
          duration: Duration(milliseconds: 60),
          curve: Curves.easeOut,
          transform: Matrix4.translationValues(0, offset, 0),
          child: Column(
            children: <Widget>[
              Container(
                height: widget.height,
                decoration: new BoxDecoration(
                  boxShadow: [
                    BoxShadow(
                      color: Colors.black.withAlpha(40),
                      blurRadius: 12.5,
                      spreadRadius: 0.0,
                    )
                  ],
                  borderRadius: BorderRadius.all(Radius.circular(10)),
                ),
                child: ClipRRect(
                  borderRadius: BorderRadius.all(Radius.circular(10)),
                  child: Stack(
                    children: [
                      CachedNetworkImage(
                        fit: BoxFit.cover,
                        imageUrl: widget.metaItem.imageUrl,
                        fadeInDuration: Duration(milliseconds: 50),
                        errorWidget: (context, url, error) => new Icon(Icons.error),
                      ),
                    ],
                  ),
                ),
              ),
              Padding(
                padding: const EdgeInsets.only(top: 8.0, left: 4.0, right: 4.0),
                child: Row(
                  children: <Widget>[
                    Expanded(
                      child: Text(
                        widget.metaItem.title,
                        textAlign: TextAlign.left,
                        style: TextStyle(fontWeight: FontWeight.w700, fontSize: 17.0),
                      ),
                    ),
                  ],
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

onTapDown: (details) {
  setState(() {
    offset = -10;
  });
},
onTapUp: (details) {
  setState(() {
    offset = 0;
  });
},
onPointerDown: (PointerDownEvent event) {
  setState(() {
    offset = -10;
  });
},
onPointerUp: (PointerUpEvent event) {
  setState(() {
    offset = 0;
  });
},