androidmotionevent事故响应机制

  • Post category:other

Android MotionEvent 事件响应机制

Android中的MotionEvent是指用户在屏幕上的触摸事件,包括按下、移动、抬起等操作。在Android中,MotionEvent事件响应机制是指当触摸屏幕时,系统如何处理这些事件并响应用户的操作。本攻略将介绍Android中的MotionEvent事件响应机制,包括事件发、事件拦截和事件处理等内容。

事件分发

在Android中,当用户触摸屏幕时,系统会将触摸事件分发给当前屏幕上的所有View,以便它们能够响应用户的操作。事件分发的过程是从外向内逐层遍历View树的过程,直到找到最终的目标View。

事件分发的过程包括以下几个步骤:

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    // 事件分发
    boolean handled = false;
    if (onInterceptTouchEvent(ev)) {
        handled = onTouchEvent(ev);
    } else {
        handled = child.dispatchTouchEvent(ev);
    }
    return handled;
}
  1. 系统将触摸事件传递给Activity的dispatchTouchEvent()方法。
  2. dispatchTouchEvent()方法将事件传递给根ViewGroup的dispatchTouchEvent()方法。
  3. dispatchTouchEvent()方法将事件传递给子View的dispatchTouchEvent方法
  4. 如果子View没有消费事件,则将事件传递给父View的dispatchTouchEvent()方法。
  5. 如果父View也没有消费事件,则将事件传递给Activity的onTouchEvent()方法。

在事件分发的过程中,如果某个View消费了事件,则后续的事件将不再传递给其他View。

事件拦截

在Android中,事件拦截是指当某个View拦截了事件后,后续的事件将不再传递给其他View。事件拦截的过程是在事件分发的过程中进行的。

事件拦截的过程包括以下几步骤:

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    // 事件拦截
    boolean intercepted = false;
    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
        intercepted = false;
    } else {
        intercepted = true;
    }
    return intercepted;
}
  1. 系统将触摸事件传递给Activity的dispatchTouchEvent()方法。
  2. dispatchTouchEvent()方法将事件传递给根ViewGroup的dispatchTouchEvent()方法。
  3. dispatchTouchEvent()方法将事件传递给子View的dispatchTouchEvent()方法。
  4. 子View需要拦截事件,则将事件传递给子View的onInterceptTouchEvent()方法。
  5. 如果子View拦截了事件,则后续的事件将不再传递给其他View。
  6. 如果子View没有拦截事件,则将事件传递给子View的onTouchEvent()方法。
  7. 如果子View没有消费事件,则将事件传递给父View的dispatchTouchEvent()方法。
  8. 如果父View也没有消费事件,则将事件传递给Activity的onTouchEvent()方法。

在事件拦截的过程中,如果某个View拦截了事件,则后续的事件将不再递给其他View。

事件处理

在Android中,事件处理是指当某个View消费了事件后,对事件进行相应的处理。事件处理的过程是在事件分发的过程中进行的。

事件处理的过程包括以下几个步骤:

@Override
public boolean onTouchEvent(MotionEvent ev) {
    // 事件处理
    boolean handled = false;
    switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            handled = true;
            break;
        case MotionEvent.ACTION_MOVE:
            handled = true;
            break;
        case MotionEvent.ACTION_UP:
            handled = true;
            break;
    }
    return handled;
}
  1. 系统将摸事件传递给Activity的dispatchTouchEvent()方法。
  2. dispatchTouchEvent()方法将事件传递给根ViewGroup的dispatchTouchEvent()方法。
  3. dispatchTouchEvent()方法将事件传递给子View的dispatchTouchEvent()方法。
  4. 如果子View需要拦截事件,则将事件传递给子View的onInterceptTouchEvent()方法。
  5. 如果子View拦截了事件,则将事件传递给子View的onTouchEvent()方法。
  6. 如果子View消费了事件,则事件处理结束。
  7. 如果子View没有消费事件,则将事件传递给父View的dispatchTouchEvent()方法。
  8. 如果父View也没有消费事件,则将事件传递给Activity的onTouchEvent()方法。

在事件处理的过程中,如果某个View消费了事件,则后续的事件将不再传给其他View。

示例说明

以下是两个关于Android MotionEvent事件响应机制的示例:

示例一

在这个示例中,我们创建一个自定义ViewGroup,并在其中添加两个子View。我们将重写dispatchTouchEvent()方法和onTouchEvent()方法,以便在事件分发和事件处理过程中输出日志信息。

class MyViewGroup extends ViewGroup {
    private static final String TAG = "MyViewGroup";

    public MyViewGroup(Context context) {
        super(context);
    }

    public MyViewGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.d(TAG, "dispatchTouchEvent: " + ev.getAction());
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        Log.d(TAG, "onTouchEvent: " + ev.getAction());
        return super.onTouchEvent(ev);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        // 布局子View
    }
}

在上面的示例中,我们重写了dispatchTouchEvent()onTouchEvent()方法,并在这两个方法中输出了日志信息。当用户触摸屏幕时,系统会将触摸事件分发给MyViewGroup,并在事件分发和事件处理过程中输出日志信息。

示例二

在这个示例中,我们将创建一个自定义View,并在其中重写onTouchEvent()方法,以便在事件处理过程中输出日志信息。

public class MyView extends View {
    private static final String TAG = "MyView";

    public MyView(Context context) {
        super(context);
    }

    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        Log.d(TAG, "onTouchEvent: " + ev.getAction());
        return true;
    }
}

在上面的示例中,我们重写了onTouchEvent()方法,并在这个方法中输出了日志信息。当用户触屏幕时,系统会将触摸事件传递给MyView,并在事件处理过程中输出日志信息。

注意事项

在使用 MotionEvent事件响应机制时需要注意以下点:

  • 事件分发、事件拦截和事件处理是在事件分发的过程中进行的。
  • 如果某个View消费了事件,则后续的事件将不再递给其他View。
  • 如果某个View拦截了事件,则后续的事件将不再传递给其他View。

结论

Android MotionEvent事件响应机制是指当用户触摸屏幕时,系统如何处理这些事件并响应用户的操作。事件分发、事件拦截和事件处理是在事件分发的过程中进行的。如果某个View消费了事件后续的事件将不再传递给其他View。如果某个View拦截了事件,则后续的事件将不再递给其他View。