【问题标题】: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 并重建应用程序

标签: flutter dart flutter-web


【解决方案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 之前添加一些延迟
  • 它不起作用
  • 你能分享我会检查的示例代码
猜你喜欢
  • 2021-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-26
  • 2015-07-14
  • 1970-01-01
  • 2019-04-09
  • 1970-01-01
相关资源
最近更新 更多