在悬停时颤动web墨水井导致异常



当我悬停图标按钮,然后悬停到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,
)),
),
);

IconButton打印悬停动作,从InkWell区域的IconButton打印悬停动作:

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],
),
);
}
}
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,
);
}
}

最新更新