MouseRegion
MouseRegion小部件 MouseRegion会暴露一些与鼠标有关的事件。这些事件包括:
OnEnter, which will trigger when your mouse enters the Widget.
OnExit, which will trigger when your mouse leaves the Widget.
OnHover, which will trigger both when your mouse enters the Widget and on every subsequent move inside the Widget.
所有这些实际上都是指针事件,它们返回有关用户指针的各种信息。在这里,我们将查看用户鼠标在包含小部件内的当前位置,该位置存储在Offset的伪装下。
class _MyHoverableWidgetState extends State<MyHoverableWidget>{
// Our state
bool amIHovering = false;
Offset exitFrom = Offset(0,0);
return MouseRegion(
onEnter: (PointerDetails details) => setState(() => amIHovering = true),
onExit: (PointerDetails details) => setState(() {
amIHovering = false;
exitFrom = details.localPosition; // You can use details.position if you are interested in the global position of your pointer.
}),
child: Container(
width: 200,
height: 200,
child: Center(
child:Text(amIHovering ? "Look mom, I'm hovering" : "I exited from: $exitFrom"),
),
),
);
}
MouseRegion.onHover|Enter|Exit
、Inkwell.onHover
或Listener.onPointerHover
等解决方案,它们看起来在DartPad中调试时还可以,但是在您的设备/模拟器上将不会响应或以其他方式表现奇怪(例如,MouseRegion.onHover
将在移动端触发点击事件,如果您没有仔细阅读属性,则可能会感到困惑)。Listener.onPointerMove
并手动对选择区域进行RenderBox
的命中测试,已经在这里和这里讨论过。 (后者还有一个明确计算自己使用Rect
表示边界框的答案,该边界框位于您要击中的全局坐标系中。据推测Path.contains
可以用于执行非矩形命中区域的相同操作。)很遗憾,您不能使用 GestureDetecture
,而是需要使用 MouseRegion
。
我正在使用 答案 的思路,但我会进行修改,因为它对我不起作用。
该答案使用了 PointerDetails
,但对我没有用。
相反,我将使用 PointerEvent
。
// inside your current widget
class _MyHoverableWidgetState extends State<MyHoverableWidget>{
// some previous code of your class //
// define a class variable to store the current state of your mouse pointer
bool amIHovering = false;
// store the position where your mouse pointer left the widget
Offset exitFrom = Offset(0,0);
return MouseRegion(
// callback when your mouse pointer enters the underlying widget
// here you have to use 'PointerEvent'
onEnter: (PointerEvent details) => setState(() => amIHovering = true),
// callback when your mouse pointer leaves the underlying widget
onExit: (PointerEvent details) => setState(() {
amIHovering = false;
// storing the exit position
exitFrom = details.localPosition; // You can use details.position if you are interested in the global position of your pointer.
}),
// your underlying widget, can be anything
child: Container(
width: 200,
height: 200,
child: Center(
child:Text(amIHovering ? "Look mom, I'm hovering" : "I exited from: $exitFrom"),
),
),
);
}
InkWell
Widget ! - ChrissiInkWell(
onHover: (value)
{
//Do something
},
onTap: ()
{
//Do something
},
child: Container(),
)
您可以创建一个非常小的框,当拖动时将其移动,然后实现一些碰撞(使用此包:https://pub.dev/packages/slowly_moving_widgets_field),并检查您的小框是否与GestureDetector的框发生碰撞。
如果发生碰撞 -> 返回hovered 如果没有 -> 不是hovered
我不熟悉使用 GestureDetector
实现此功能的方法,因为我认为所有手势都需要在 GestureDetector
小部件内开始。可能可以将容器包装在 GestureDetector
中,并确定指针何时位于容器顶部。
如果您正在尝试在Web或桌面设备上执行此操作,则可以使用 MouseRegion 小部件。如果您转到链接,您可以看到它如何轻松检测鼠标进入和退出。
还有 Draggable 小部件,可与 DraggableTarget
小部件一起使用,以执行一些很酷的事情。
简而言之,如果目标边界位于坐标x1(0),x2(10),y1(0),y2(8)内
// Sample callbackCode to check if within
// x and y are the positions returned from the gesture detector
bool isWithinTarget(x, y)
{
if (x > x1 && x < x2 && y > y1 && y < y2) {
// The pointer is within the target widget
// Perform required action
// Rebuild widget tree if necessary
return true;
}
return false;
}
您可以将您的Gesturedetector或任何小部件包装在Listener类中,并监听拖动的位置,根据这些值执行一些任务。
MouseRegion
的事件是否也会被手势触发?(例如在iOS和Android中,而不是在Web或桌面上) - Hossein Hadi