Android事件传递机制

 

 

Android事件构成

在Android中,所有的事件都由如下三个部分作为基础:

  • 按下(ACTION_DOWN)
  • 移动(ACTION_MOVE)
  • 抬起(ACTION_UP)

View.java

public boolean dispatchTouchEvent(MotionEvent event)
public boolean onTouchEvent(MotionEvent event) 

ViewGroup.java

 public boolean dispatchTouchEvent(MotionEvent event)
public boolean onTouchEvent(MotionEvent event) 
public boolean onInterceptTouchEvent(MotionEvent event)


在Android中,所有的事件都是从开始经过传递到完成事件的消费,这些方法的返回值就决定了某一事件是否是继续往下传,还是被拦截了,或是被消费了。

  • dispatchTouchEvent方法用于事件的分发,Android中所有的事件都必须经过这个方法的分发,然后决定是自身消费当前事件还是继续往下分发给子控件处理。返回true表示不继续分发,事件没有被消费。返回false则继续往下分发,如果是ViewGroup则分发给onInterceptTouchEvent进行判断是否拦截该事件。
  • onTouchEvent方法用于事件的处理,返回true表示消费处理当前事件,返回false则不处理,交给子控件进行继续分发。
  • onInterceptTouchEvent是ViewGroup中才有的方法,View中没有,它的作用是负责事件的拦截,返回true的时候表示拦截当前事件,不继续往下分发,交给自身的onTouchEvent进行处理。返回false则不拦截,继续往下传。这是ViewGroup特有的方法,因为ViewGroup中可能还有子View,而在Android中View中是不能再包含子View的(iOS可以)。
事件流程图:

总结

  • Android中事件传递按照从上到下进行层级传递,事件处理从Activity开始到ViewGroup再到View。
  • 事件传递方法包括dispatchTouchEventonTouchEventonInterceptTouchEvent,其中前两个是View和ViewGroup都有的,最后一个是只有ViewGroup才有的方法。这三个方法的作用分别是负责事件分发、事件处理、事件拦截。
  • onTouch事件要先于onClick事件执行,onTouch在事件分发方法dispatchTouchEvent中调用,而onClick在事件处理方法onTouchEvent中被调用,onTouchEvent要后于dispatchTouchEvent方法的调用。
  • 若view的onTouch中的方法返回true,则不会执行view的onTouchEvent,则在view中也不会执行onclick方法。
  • 若view 和viewgroup的ontouch方法都为true,则都不会触发onTouchEvent,则不会执行onclick方法。

public class MainActivity extends Activity {
    private RTButton button;

    private RTLayout rtlayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = (RTButton) this.findViewById(R.id.btn);
        rtlayout = (RTLayout)findViewById(R.id.myLayout);
        button.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    System.out.println("RTButton---onTouch---DOWN");
                    break;
                case MotionEvent.ACTION_MOVE:
                    System.out.println("RTButton---onTouch---MOVE");
                    break;
                case MotionEvent.ACTION_UP:
                    System.out.println("RTButton---onTouch---UP");
                    break;
                default:
                    break;
                }
                return false;
            }
        });

        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                System.out.println("RTButton clicked!");
            }
        });
        rtlayout.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    System.out.println("RTLayout---onTouch---DOWN");
                    break;
                case MotionEvent.ACTION_MOVE:
                    System.out.println("RTLayout---onTouch---MOVE");
                    break;
                case MotionEvent.ACTION_UP:
                    System.out.println("RTLayout---onTouch---UP");
                    break;
                default:
                    break;
                }
                return true;
            }
        });

        rtlayout.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                System.out.println("RTLayout clicked!");
            }
        });
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            System.out.println("Activity---dispatchTouchEvent---DOWN");
            break;
        case MotionEvent.ACTION_MOVE:
            System.out.println("Activity---dispatchTouchEvent---MOVE");
            break;
        case MotionEvent.ACTION_UP:
            System.out.println("Activity---dispatchTouchEvent---UP");
            break;
        default:
            break;
        }
        return super.dispatchTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            System.out.println("Activity---onTouchEvent---DOWN");
            break;
        case MotionEvent.ACTION_MOVE:
            System.out.println("Activity---onTouchEvent---MOVE");
            break;
        case MotionEvent.ACTION_UP:
            System.out.println("Activity---onTouchEvent---UP");
            break;
        default:
            break;
        }
        return super.onTouchEvent(event);
    }
}
public class RTButton extends Button {
    public RTButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            System.out.println("RTButton---dispatchTouchEvent---DOWN");
            break;
        case MotionEvent.ACTION_MOVE:
            System.out.println("RTButton---dispatchTouchEvent---MOVE");
            break;
        case MotionEvent.ACTION_UP:
            System.out.println("RTButton---dispatchTouchEvent---UP");
            break;
        default:
            break;
        }
        return super.dispatchTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            System.out.println("RTButton---onTouchEvent---DOWN");
            break;
        case MotionEvent.ACTION_MOVE:
            System.out.println("RTButton---onTouchEvent---MOVE");
            break;
        case MotionEvent.ACTION_UP:
            System.out.println("RTButton---onTouchEvent---UP");
            break;
        default:
            break;
        }
        return super.onTouchEvent(event);
    }
}
public class RTLayout extends LinearLayout {
    public RTLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            System.out.println("RTLayout---dispatchTouchEvent---DOWN");
            break;
        case MotionEvent.ACTION_MOVE:
            System.out.println("RTLayout---dispatchTouchEvent---MOVE");
            break;
        case MotionEvent.ACTION_UP:
            System.out.println("RTLayout---dispatchTouchEvent---UP");
            break;
        default:
            break;
        }
        return super.dispatchTouchEvent(event);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            System.out.println("RTLayout---onInterceptTouchEvent---DOWN");
            break;
        case MotionEvent.ACTION_MOVE:
            System.out.println("RTLayout---onInterceptTouchEvent---MOVE");
            break;
        case MotionEvent.ACTION_UP:
            System.out.println("RTLayout---onInterceptTouchEvent---UP");
            break;
        default:
            break;
        }
        return super.onInterceptTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            System.out.println("RTLayout---onTouchEvent---DOWN");
            break;
        case MotionEvent.ACTION_MOVE:
            System.out.println("RTLayout---onTouchEvent---MOVE");
            break;
        case MotionEvent.ACTION_UP:
            System.out.println("RTLayout---onTouchEvent---UP");
            break;
        default:
            break;
        }
        return super.onTouchEvent(event);
    }
}

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <com.jiudao.touch.event.RTLayout
        android:id="@+id/myLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <com.jiudao.touch.event.RTButton
            android:id="@+id/btn"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Button" />
    </com.jiudao.touch.event.RTLayout>

</LinearLayout>

 

转载自:http://orgcent.com/android-touch-event-mechanism/

posted on 2014-06-04 16:08  zust  阅读(203)  评论(0)    收藏  举报