Android触摸事件传递机制(View事件传递机制)

2019-10-29  本文已影响0人  程序实现梦想

文章共分两篇,会详细介绍Activity,View,ViewGroup三者的触摸事件传递机制。一次完整的事件传递主要包括三个阶段,分别是事件的分发,拦截和消费。

1.1 触摸事件的类型

触摸事件对应的MotionEvent类,事件的类型主要有如下三种

    ACTION_DOWN:用户手指按下的操作,一个按下标志着一个触摸事件的开始。

    ACTION_MOVE:用户手指按下在抬起之前,移动的距离超过一定的值,会被判定为                                         ACTION_MOVE操作 一般手,指的轻微移动都会触发一系列的移动事件。

    ACTION_UP:用户手指离开屏幕的操作,一次抬起操作标志着一次触摸事件的结束。

1.2 事件传递的三个阶段

    分发(Dispatch):事件的分发对应这dispatchTouchEvent方法,在Android系统中所有的触摸事件都是通过这个方法分发的。

    拦截(Intercept):事件的拦截对应着onInterceptTouchEvent方法,这个方法只在ViewGroup及其子类中存在。

    消费(Consume):事件的消费对应着onTouchEvent方法。    

    在Android系统中,拥有事件传递能力的类有以下三种:

        Activity:拥有dispatchTouchEvent和onTouchEvent两个方法。

        ViewGroup:拥有dispatchTouchEvent,onInterceptTouchEvent和onTouchEvent两个方法。

        View:拥有dispatchTouchEvent和onTouchEvent两个方法。

    1.3 View事件的传递机制

       这里所说的View指ViewGroup以外的View,如TextView,Button,ImageView等。

    public class MyTextView extends AppCompatTextView {

    private static final String TAG = MyTextView.class.getSimpleName();

    public MyTextView(Context context) {

        super(context);

    }

    public MyTextView(Context context, @Nullable AttributeSet attrs) {

        super(context, attrs);

    }

    public MyTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

        super(context, attrs, defStyleAttr);

    }

    @Override

    public boolean dispatchTouchEvent(MotionEvent event) {

        switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN:

                Log.e(TAG,"dispatchTouchEvent ACTION_DOWN");

                break;

            case MotionEvent.ACTION_MOVE:

                Log.e(TAG,"dispatchTouchEvent ACTION_MOVE");

                break;

            case MotionEvent.ACTION_UP:

                Log.e(TAG,"dispatchTouchEvent ACTION_UP");

                break;

                default:

                    break;

        }

      return super.dispatchTouchEvent(event);

    }

    @Override

    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN:

                Log.e(TAG,"onTouchEvent ACTION_DOWN");

                break;

            case MotionEvent.ACTION_MOVE:

                Log.e(TAG,"onTouchEvent ACTION_MOVE");

                break;

            case MotionEvent.ACTION_UP:

                Log.e(TAG,"onTouchEvent ACTION_UP");

                break;

            default:

                break;

        }

        return super.onTouchEvent(event);

    }

}

同时定义MainActivity用来展示MyTextView,在这个Activity中,我们对MyTextView设置了点击(onClick)触摸(onTouch)监听。

public class MainActivity extends AppCompatActivity implements View.OnTouchListener , View.OnClickListener {

    private static final String TAG = MainActivity.class.getSimpleName();

    private TextView textView;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        textView = findViewById(R.id.tv);

        textView.setOnTouchListener(this);

        textView.setOnClickListener(this);

    }

    @Override

    public boolean dispatchTouchEvent(MotionEvent event) {

        switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN:

                Log.e(TAG,"dispatchTouchEvent ACTION_DOWN");

                break;

            case MotionEvent.ACTION_MOVE:

                Log.e(TAG,"dispatchTouchEvent ACTION_MOVE");

                break;

            case MotionEvent.ACTION_UP:

                Log.e(TAG,"dispatchTouchEvent ACTION_UP");

                break;

            default:

                break;

        }

        return super.dispatchTouchEvent(event);

    }

    @Override

    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN:

                Log.e(TAG,"onTouchEvent ACTION_DOWN");

                break;

            case MotionEvent.ACTION_MOVE:

                Log.e(TAG,"onTouchEvent ACTION_MOVE");

                break;

            case MotionEvent.ACTION_UP:

                Log.e(TAG,"onTouchEvent ACTION_UP");

                break;

            default:

                break;

        }

        return super.onTouchEvent(event);

    }

    @Override

    public boolean onTouch(View v, MotionEvent event) {

        switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN:

                Log.e(TAG,"MyTextView onTouch ACTION_DOWN");

                break;

            case MotionEvent.ACTION_MOVE:

                Log.e(TAG,"MyTextView onTouchEvent ACTION_MOVE");

                break;

            case MotionEvent.ACTION_UP:

                Log.e(TAG,"MyTextView onTouchEvent ACTION_UP");

                break;

            default:

                break;

        }

        return false;

    }

    @Override

    public void onClick(View v) {

        if (v.getId() == R.id.tv) {

            Log.e(TAG,"MyTextView onClick");

        }

    }

}

运行上面的代码,点击MyTextView,打印日志。

2019-10-29 16:26:55.547 14052-14052/com.hzy.mydemo E/MainActivity: dispatchTouchEvent ACTION_DOWN

2019-10-29 16:26:55.548 14052-14052/com.hzy.mydemo E/MyTextView: dispatchTouchEvent ACTION_DOWN

2019-10-29 16:26:55.548 14052-14052/com.hzy.mydemo E/MainActivity: MyTextView onTouch ACTION_DOWN

2019-10-29 16:26:55.548 14052-14052/com.hzy.mydemo E/MyTextView: onTouchEvent ACTION_DOWN

2019-10-29 16:26:55.566 14052-14052/com.hzy.mydemo E/MainActivity: dispatchTouchEvent ACTIO

2019-10-29 16:26:55.645 14052-14052/com.hzy.mydemo E/MainActivity: dispatchTouchEvent ACTION_UP

2019-10-29 16:26:55.646 14052-14052/com.hzy.mydemo E/MyTextView: dispatchTouchEvent ACTION_UP

2019-10-29 16:26:55.646 14052-14052/com.hzy.mydemo E/MainActivity: MyTextView onTouchEvent ACTION_UP

2019-10-29 16:26:55.646 14052-14052/com.hzy.mydemo E/MyTextView: onTouchEvent ACTION_UP

2019-10-29 16:26:55.648 14052-14052/com.hzy.mydemo E/MainActivity: MyTextView onClick

不同的返回方式传递流程相差甚远,请看流程图

上一篇下一篇

猜你喜欢

热点阅读