在Android中的多个视图上同时触摸事件处理

Fal*_*ity 6 android android-view android-viewpager android-touch-event

考虑下图中的示例,

在此输入图像描述

我正在寻找一种解决方案,将触摸事件从画布View传递给Viewpager.这对于同时在两个视图上应用相同数量的缩放是必要的.

这是对正在发生的事情的技术描述,

(让我们将视图视为A,BC)

A.父母观点

B.观点

C.查看寻呼机

在子项(B&C)上调用dispatchTouchEvent()之前,A.dispatchTouchEvent()将首先调用A.onInterceptTouchEvent()以查看视图组是否有兴趣拦截事件.

因此,如果A.onTouchEvent()返回false,则返回到B.onTouchEvent().如果返回false,则返回到C.onTouchEvent()并继续照常调度.

返回真实时,

  1. ACTION_CANCEL将被派遣给所有孩子.

  2. 如果已定义,则事件侦听器(OnTouchListener.onTouch())将使用所有后续手势事件(直到ACTION_UP/ACTION_CANCEL),否则将在A级别使用事件处理程序A.onTouchEvent().

在这一点上我可以从父到子视图传递事件,但不能让孩子2视图.&C一起处理事件(在两个视图上应用相同数量的缩放).

有没有办法将触摸事件从父视图传递给子视图,以便他们可以同时处理事件?

这是我的布局设置,

<RelativeLayout
    android:id="@+id/layoutParent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFFFFFFF">

            <com.androidapp.NonSwipeableViewPager
                android:id="@+id/pager"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_gravity="center"
                android:background="@color/transparent" />

            <com.androidapp.DrawingView
                android:id="@+id/drawing"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@color/transparent" />

</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

Pro*_*kar 5

如果我没记错的话,您希望在顶视图和底视图上处理相同的触摸事件。根据 Android 触摸架构,您不能同时处理来自多个视图的触摸事件。要么你必须在方法内部处理它,onTouchEvent()要么传递给下一个视图。您还需要等到顶视图完成处理MotionEvent() 并让子视图处理。

这是使用RxAndroid方法的可能解决方案,

在您的画布视图中MotionEvent()

@Override
    public boolean onTouchEvent(MotionEvent event) {

    // process all touch events (UP/DOWN/MOVE)

    //send events as observable
    RxBus.getInstance().sendMotionEvent(event);

    return true;
}
Run Code Online (Sandbox Code Playgroud)

这将观察运动事件并通知所有观察者。

现在,在您的 viewpageronResume()订阅运动事件中,这样无论何时从画布进行更改,它都会立即传递事件。

Subscription RxBus _rxBus = RxBus.getInstance();
        subscription = _rxBus.getMotionEvent()
                .subscribe(new Action1<MotionEvent>() {
                    @Override
                    public void call(MotionEvent event) {
                       // call the onTouchEvent of your widget e.g. ImageView and pass the received event
                       // this will apply the same touch event that was applied in the canvas 

                        // .onTouchEvent(event) is important to override the onTouchEvent() of your widget that will use the touch event
                        imageView.onTouchEvent(event);
                    }
            });
Run Code Online (Sandbox Code Playgroud)

RxBus类如下,

public class RxBus {

    private static RxBus instance;

    private final PublishSubject<MotionEvent> motion_event = PublishSubject.create();

    public static RxBus getInstance() {
        if (instance == null) {
            instance = new RxBus();
        }
        return instance;
    }

    public void sendMotionEvent(MotionEvent motionEvent) {
        motion_event.onNext(motion_event);
    }

    public Observable<MotionEvent> getMotionEvent() {
        return motion_event;
    }
}
Run Code Online (Sandbox Code Playgroud)