将触摸事件转发到动态附加视图,无需抬起手指

时间:2015-02-24 10:31:50

标签: android

我有一个问题,我现在正在努力。

我有一个带有Button和容器的布局。

<FrameLayout ... >

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

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

</FrameLayout>

我的目标是,当我长按按钮时,我会将自定义视图 MyCustomView附加到容器中并按住手指。 然后,理想情况下应将ACTION_MOVEACTION_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 - 事件(这是启动事件流到视图所需的)。 当我附加ACTION_DOWN时,手动生成和发送MyCustomView - 事件也不起作用。

虽然在研究中我发现这篇文章,它基本上是相同的要求,但对于iOS(也没有提供优雅的解决方案,其他点击捕获叠加视图)):How to preserve touch event after new view is added by long press

请注意,我想避免在主视图上进行某种全局覆盖,我希望解决方案尽可能地插拔和移植。

感谢您的任何建议。

1 个答案:

答案 0 :(得分:2)

在评论中提示之后回答我自己的问题:

我使用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(可能需要也可能不需要对坐标进行一些翻译) - etvoilà。

感谢pskink提示。