【问题标题】:Flutter - How to cancel pointer up eventFlutter - 如何取消指针向上事件
【发布时间】:2020-07-06 05:34:07
【问题描述】:

https://api.flutter.dev/flutter/widgets/Listener-class.html

在此示例中,如果指针在蓝色容器之外释放,则视为释放。当指针到达蓝色容器之外时如何取消指针事件?我已经尝试在我的特定用例中忽略指针和吸收指针,其中我在一列中有两个孩子,并且侦听器附加到第二个,但第一个也发出指针向上事件。我想要 PointerUpEvent 的功能,因为我想获取本地位置,所以 GestureDetector 的 onPanEnd 不起作用。

【问题讨论】:

    标签: flutter


    【解决方案1】:

    创建一个方法来验证指针是否在子节点之外。然后你可以在你的 onTapUp 事件中调节它。

    类似这样的:

    获取您孩子的大小

    final RenderBox childRenderBox = _childKey.currentContext.findRenderObject() as RenderBox;
    final Size childSize = childRenderBox.size;
    

    将孩子的局部坐标系转换为以逻辑像素为单位的全局坐标系

    final Offset childPosition = childRenderBox.localToGlobal(Offset.zero);
    

    检查touchPosition(Pointer)是否在child或box之外

    return touchPosition.dx < childPosition.dx ||
        touchPosition.dx > childPosition.dx + childSize.width ||
        touchPosition.dy < childPosition.dy ||
        touchPosition.dy > childPosition.dy + childSize.height;
    

    最后,你有一个方法可以检查指针是否在外面。

    bool _isOutsideChildBox(Offset touchPosition) {
    final RenderBox childRenderBox =
        _childKey.currentContext.findRenderObject() as RenderBox;
    final Size childSize = childRenderBox.size;
    final Offset childPosition = childRenderBox.localToGlobal(Offset.zero);
    
    return touchPosition.dx < childPosition.dx ||
        touchPosition.dx > childPosition.dx + childSize.width ||
        touchPosition.dy < childPosition.dy ||
        touchPosition.dy > childPosition.dy + childSize.height;
    }
    

    现在在你的 onTapUp 事件中检查触摸的位置是否在外面,然后做一些事情。

    void _onTapUp(PointerUpEvent event) {
        if(_isOutSideChildBox(event.position)){
          dont emit release...
        }
    }
    

    【讨论】:

    • 你好,很好的答案谢谢你,我只是在尝试!我可以知道将孩子包装在布局构建器中以获取上下文是否可以而不是使用键?
    【解决方案2】:

    使用 LayoutBuilder 包装侦听器并从 LayoutBuilder 传递约束以及从 PointerUpEvent 传递详细信息可用于验证触摸是否在边界内。

    bool _isInsideBox(BoxConstraints constraints, PointerUpEvent details) {
        return details.localPosition.dx >= 0.0 &&
        details.localPosition.dy >= 0.0 &&
        details.localPosition.dx <= constraints.maxWidth &&
        details.localPosition.dy <= constraints.maxHeight;
    }
    

    然后简单的调用onPointerUp里面的函数

    void _onPointerUp(PointerUpEvent details) {
       if(_isInsideBox(constraints,details)){
         //do something
        }
       else{
        // do nothing
        }
    }
    

    @Zolicious 给出了更具体的解决方案

    【讨论】:

    • 这是我猜想的最好的方法
    • 你用什么例子来测试这段代码?如果可行,我可以将其标记为解决方案
    • 我没有测试这个,我假设你测试了这个,“看起来”像一个更好的方法
    【解决方案3】:

    一种更简单的方法是仍然使用 GestureDetector,如果您正在寻找平移结束时的本地位置,请使用 onPanEnd()onPanUpdate()

    当平移结束时,使用 onPanUpdate 提供的最后一个DragUpdateDetails 来获取位置

    【讨论】:

    • 如果指针离开孩子我想获得最后一个成功的 PointerUp 值,但使用 GestureDetector onPanUpdate 不断更新指针离开孩子时不需要的值我想取消整个事件跨度>
    • 我试过鼠标区域它似乎不适合我
    • 平移更新仅在指针向下时发生,如果您在指针仍在框的边界内时询问最后一个指针位置,请使用上述方法和 MouseRegion
    • 我会尝试 panUpdate 但 MouseRegion 似乎对我不起作用。
    • 我在模拟器上试过了,鼠标区域不行
    猜你喜欢
    • 1970-01-01
    • 2019-09-05
    • 1970-01-01
    • 2019-03-11
    • 2021-03-20
    • 2013-01-04
    • 2015-01-20
    • 1970-01-01
    • 2020-03-19
    相关资源
    最近更新 更多