0
点赞
收藏
分享

微信扫一扫

flutter中InkWell 和 GestureDetector快速、频繁点击时表现出不响应或“点不到”的情况分析

飞空之羽 2024-09-29 阅读 16

背景:
之前没有详细的用到这一块,最近自己做了一个竞速类的工具,主打一个快速输入之后快速提交。

结果,老是提交之后,不能快速的拿到输入栏的结果,明明已经输入了,却显示null。
一开始以为是放在setState方法中,有延迟,于是拿了出来,不在setState方法中改变初始值。

后面发现还是不行,输入快,点击快的情况下,还是会把输入的内容漏掉。

这时的我不得不分析我是否用错了控件。

原来代码如下:

class CustomButton extends StatelessWidget {
  final String label;
  final VoidCallback onTap;
  final VoidCallback? onLongPress; // 添加这个字段
  static const TextStyle top_two_style = TextStyle(
      fontSize: 18, color: Color(0xff353e4d), fontWeight: FontWeight.w500);
  const CustomButton({Key? key, required this.label, required this.onTap,this.onLongPress}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(1),
      child: Material(
        color: AppColors.APPKeyLightColor,
        shape: const RoundedRectangleBorder(
          borderRadius: BorderRadius.all(Radius.circular(2)),
        ),
        child: InkWell(
          onTap: onTap,
          onLongPress: onLongPress, // 可以为空
          splashColor: AppColors.APPKeyDarkMoreColor, // 按下时的颜色
          borderRadius: BorderRadius.all(Radius.circular(2)),
          child: Container(
            padding: const EdgeInsets.all(9),
            alignment: Alignment.center,
            child: Text(
              label,
              style: top_two_style,
            ),
          ),
        ),
      ),
    );
  }
}

我怀疑是InkWell的问题,因为看源码可以知道,他有个水波纹,有一个固定的延迟,用于显示水波纹动画效果。这种延迟在快速点击时会影响响应速度。

之前使用他是因为他自带背景色,方便简单,没想到,这个成了问题所在:

于是改了代码

class CustomButton extends StatefulWidget {
  final String label;
  final VoidCallback onTap;
  final VoidCallback? onLongPress;

  const CustomButton({
    Key? key,
    required this.label,
    required this.onTap,
    this.onLongPress,
  }) : super(key: key);

  @override
  _CustomButtonState createState() => _CustomButtonState();
}

class _CustomButtonState extends State<CustomButton> {
  bool _isPressed = false;

  static const TextStyle top_two_style = TextStyle(
    fontSize: 18,
    color: Color(0xff353e4d),
    fontWeight: FontWeight.w500,
  );

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(1),
      child: GestureDetector(
        onTap: widget.onTap,
        onLongPress: widget.onLongPress,
        onTapDown: (_) {
          setState(() {
            _isPressed = true;
          });
        },
        onTapUp: (_) {
          setState(() {
            _isPressed = false;
          });
        },
        onTapCancel: () {
          setState(() {
            _isPressed = false;
          });
        },
        child: Container(
          decoration: BoxDecoration(
            color: _isPressed
                ? AppColors.APPKeyDarkMoreColor // 仅短按时改变背景色
                : AppColors.APPKeyLightColor,  // 默认颜色
            borderRadius: BorderRadius.circular(2),
          ),
          padding: const EdgeInsets.all(9),
          alignment: Alignment.center,
          child: Text(
            widget.label,
            style: top_two_style,
          ),
        ),
      ),
    );
  }
}

GestureDetector能实现更复杂的效果,这里也只好换成这个了。就是代码量加了不少。

于是就完美解决。

注意这个坑,有的需要水波纹,有的不需要水波纹,谨慎处理。

当然排查的时候还有这几个点:

这几个都可能造成响应慢的情况,逐一分析即可。

举报
0 条评论