颤动的网络墨水池悬停导致异常

Posted

技术标签:

【中文标题】颤动的网络墨水池悬停导致异常【英文标题】:flutter web inkwell onhover causing exception 【发布时间】:2022-01-01 18:09:36 【问题描述】:

当我将图标按钮悬停,然后始终悬停在 InkWell 区域中的另一个位置时,我得到了这个异常:

Error: Assertion failed:
../…/animation/animation_controller.dart:487
_ticker != null
"AnimationController.reverse() called after AnimationController.dispose()\nAnimationController methods should not be used after calling dispose."
    at Object.throw_ [as throw] (http://localhost:38805/dart_sdk.js:5063:11)
    at Object.assertFailed (http://localhost:38805/dart_sdk.js:4988:15)
at animation_controller.AnimationController.new.reverse (http://localhost:38805/packages/flutter/src/animation/animation_controller.dart.lib.js:305:42)
    at internalCallback (http://localhost:38805/dart_sdk.js:26215:11)

这是代码:

return Material(
      child: InkWell(
        onTap: widget.onTap,
        onHover: (bool isHoverIn) 
          print("isHoverIN: $isHoverIn iscancel: $isCancelButtonVisible");
          // (isHoverIn) 
          if (isHoverIn != isCancelButtonVisible)
            setState(() 
              isCancelButtonVisible = isHoverIn;
            );
        ,
        child: ClipRRect(
            borderRadius: BorderRadius.circular(10.0),
            child: Container(
              height: boxSize,
              width: boxSize,
              decoration: BoxDecoration(
                image: DecorationImage(
                  image: widget.imageData.image!.image,
                  fit: BoxFit.cover,
                ),
                border: Border.all(
                  color: Colors.grey,
                  width: 5,
                ),
                borderRadius: BorderRadius.circular(12),
              ),
              child: isCancelButtonVisible
                  ? Align(
                      alignment: Alignment.topRight,
                      child: IconButton(
                        iconSize: 20,
                        icon: const Icon(Icons.cancel),
                        tooltip: 'rimuovi',
                        onPressed: () => widget.onRemove(widget.position),
                      ),
                    )
                  : null,
            )),
      ),
    );

InkWell 区域中打印来自IconButtonIconButton 的悬停动作:

isHoverIN: true iscancel: false
isHoverIN: false iscancel: true
isHoverIN: true iscancel: false

这是完整的小部件:

class _ProductMediaViewer extends StatefulWidget 
  final int position;
  final ProductVariantImage imageData;
  final void Function(int, int) swap;
  final void Function(int) onRemove;
  final void Function() onTap;
  final double boxSize;

  const _ProductMediaViewer(
    Key? key,
    required this.position,
    required this.imageData,
    required this.swap,
    required this.onRemove,
    required this.onTap,
    required this.boxSize,
  ) : super(key: key);

  @override
  _ProductMediaViewerState createState() => _ProductMediaViewerState();


class _ProductMediaViewerState extends State<_ProductMediaViewer> 
  bool isCancelButtonVisible = false;

  Widget getMediaContentBox(bool isTransparent) 
    final boxSize =
        widget.position == -1 ? widget.boxSize * 2.5 : widget.boxSize;
    return Material(
      color: Colors.transparent,
      child: Opacity(
        opacity: isTransparent ? 0.45 : 1.0,
        child: InkWell(
          // TODO
          onTap: widget.onTap,
          onHover: (bool isHoverIn) 
            print("isHoverIN: $isHoverIn iscancel: $isCancelButtonVisible");
            // (isHoverIn) 
            if (isHoverIn != isCancelButtonVisible)
              setState(() 
                isCancelButtonVisible = isHoverIn;
              );
          ,
          child: ClipRRect(
              borderRadius: BorderRadius.circular(10.0),
              child: Container(
                height: boxSize,
                width: boxSize,
                decoration: BoxDecoration(
                  image: DecorationImage(
                    image: widget.imageData.image!.image,
                    fit: BoxFit.cover,
                  ),
                  border: Border.all(
                    color: Colors.grey,
                    width: 5,
                  ),
                  borderRadius: BorderRadius.circular(12),
                ),
                child: isCancelButtonVisible
                    ? Align(
                        alignment: Alignment.topRight,
                        child: IconButton(
                          iconSize: 20,
                          icon: const Icon(Icons.cancel),
                          tooltip: 'rimuovi',
                          onPressed: () => widget.onRemove(widget.position),
                        ),
                      )
                    : null,
              )),
        ),
      ),
    );
  

  @override
  Widget build(BuildContext context) 
    final boxSize =
        widget.position == -1 ? widget.boxSize * 2.5 : widget.boxSize;
    return Draggable<int>(
      onDragCompleted: () => isCancelButtonVisible = false,
      maxSimultaneousDrags: 1,
      data: widget.position,
      child: DragTarget<int>(
        builder: (
          BuildContext context,
          List<dynamic> accepted,
          List<dynamic> rejected,
        ) 
          return getMediaContentBox(false);
        ,
        onAccept: (int draggablePosition) 
          widget.swap(draggablePosition, widget.position);
          print("draggpos: $draggablePosition");
          print("pos: $widget.position");
        ,
      ),
      feedback: getMediaContentBox(true),
      childWhenDragging: Container(
        height: boxSize,
        width: boxSize,
        color: Colors.grey[200],
      ),
    );
  

【问题讨论】:

您能否包含将重现相同错误的完整小部件,我未能产生错误,尝试使用flutter clean 并重建应用程序 【参考方案1】:
You can use this widget

 class HoverWidget extends StatefulWidget 
      final Widget child;
      final Widget hoverChild;
      final Function(PointerEnterEvent event) onHover;
      const HoverWidget(
          Key key,
          @required this.child,
          @required this.hoverChild,
          @required this.onHover)
          : assert(child != null && hoverChild != null && onHover != null),
            super(key: key);
    
      @override
      _HoverWidgetState createState() => _HoverWidgetState();
    
    
    class _HoverWidgetState extends State<HoverWidget> 
      bool _isHover = false;
      @override
      void initState() 
        super.initState();
      
    
      @override
      Widget build(BuildContext context) 
        return MouseRegion(
          cursor: SystemMouseCursors.click,
          onEnter: (event) 
            setState(() 
              _isHover = true;
            );
            widget.onHover(event);
          ,
          onExit: (event) 
            setState(() 
              _isHover = false;
            );
          ,
          child: _isHover ? widget.hoverChild : widget.child,
        );
      
    

【讨论】:

这个小部件很好,但我得到了同样的错误。 在 setstate 之前添加一些延迟 它不起作用 你能分享我会检查的示例代码

以上是关于颤动的网络墨水池悬停导致异常的主要内容,如果未能解决你的问题,请参考以下文章

构建失败并出现异常 - 颤动

颤动的网页,文本异常裁剪

Twitter登录异常颤动

处理异常 HTTP 请求颤动

如何在颤动中使用 CachedNetworkImage 处理 404 异常

颤动的firebase错误“失败:构建失败并出现异常”