【问题标题】:Forward touch event to dynamically attached view, without lifting finger将触摸事件转发到动态附加视图,无需抬起手指
【发布时间】:2015-02-24 10:31:49
【问题描述】:

我有一个问题我现在正在苦苦挣扎。

我有一个布局,里面有一个按钮和一个容器。

<FrameLayout ... >

    <Button
        android:id="@+id/button"
        ...
    />

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/overlayContainer"/>

</FrameLayout>

我的目标是,当我长按按钮时,我将 自定义视图 MyCustomView 附加到容器并按住手指。 理想情况下,所有以下 (ACTION_MOVE, ACTION_UP) 事件都应分派到MyCustomView 并由其评估。

MyCustomView 就像一个圆形弹出菜单:它覆盖、调暗背景并显示一些选项。然后,您将按下的手指滑动到选项,将其抬起,它会触发结果。

mButton.setOnLongClickListener(new View.OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        // attach custom view to overlayContainer
        // simplified code for demonstration
        overlayContainer.addView(new MyCustomView());
        return true;
    }
});

现在我没有看到任何选项可以从按钮“窃取”ACTION_DOWN-Event(启动事件流到视图所必需的),因为我在它上面。 在我附加的MyCustomView 中手动生成和调度ACTION_DOWN-Event 也不起作用。

在研究时我在这里找到了这篇文章,它基本上是相同的要求,但对于 iOS(也没有提供优雅的解决方案,除了点击捕获覆盖视图):How to preserve touch event after new view is added by long press

请注意,我想避免在主视图上出现某种全局覆盖,我希望解决方案尽可能可插入和便携。

感谢您的任何建议。

【问题讨论】:

  • TouchDelegate 不是您想要的吗?
  • 您的意思是在 Button 上设置 TouchDelegate 并将 CustomView 传递给它?有趣的想法...
  • 你可以试试看,也可以看看TD的源码,它是如何调度MotionEvents并自己做的
  • 谢谢,我去看看
  • 是的,TouchDelegate 是关键!谢谢你。清理完所有内容后将发布答案。我有什么办法可以不止一次投票给你的提示吗? :)

标签: android


【解决方案1】:

在 cmets 提示后回答我自己的问题:

我使用TouchDelegate 的裸剥离版本解决了它(不得不扩展它,因为它不幸没有接口 - setTouchDelegate 只接受 TouchDelegate (子)类。不是 100% 干净,但效果很好。

public class CustomTouchDelegate extends TouchDelegate {

    private View mDelegateView;

    public CustomTouchDelegate(View delegateView) {
        super(new Rect(), delegateView);
        mDelegateView = delegateView;
    }

    public boolean onTouchEvent(MotionEvent event) {
        return mDelegateView.dispatchTouchEvent(event);
    }
}

然后在我的 onLongClick 方法中:

mButton.setOnLongClickListener(new View.OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        // attach custom view to overlayContainer, simplified for demonstration

        MyCustomView myMenuView = new MyCustomView()
        mButton.setTouchDelegate(new CustomTouchDelegate(myMenuView));

        // What's left out here is to mButton.setTouchDelegate = null,
        // as soon as the temporary Overlay View is removed

        overlayContainer.addView(myMenuView);
        return true;
    }
});

这样,我所有来自 Button 的 ACTION_MOVE 事件都被委托给 MyCustomView(并且可能需要也可能不需要坐标的一些转换) - 等等。

感谢 pskink 的提示。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多