Android View的事件分发

    xiaoxiao2021-03-25  102

    1、案例

    为了更好的研究View的事件转发,我们自定以一个MyButton继承Button,然后把跟事件传播有关的方法进行复写,然后添加上日志~

    MyButton

    [java]  view plain  copy package com.example.zhy_event03;      import android.content.Context;   import android.util.AttributeSet;   import android.util.Log;   import android.view.MotionEvent;   import android.widget.Button;      public class MyButton extends Button   {       private static final String TAG = MyButton.class.getSimpleName();          public MyButton(Context context, AttributeSet attrs)       {           super(context, attrs);       }          @Override       public boolean onTouchEvent(MotionEvent event)       {           int action = event.getAction();              switch (action)           {           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 dispatchTouchEvent(MotionEvent event)       {           int action = event.getAction();              switch (action)           {           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);       }             }   在onTouchEvent和dispatchTouchEvent中打印了日志~

    然后把我们自定义的按钮加到主布局文件中;

    布局文件:

    [html]  view plain  copy <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"       xmlns:tools="http://schemas.android.com/tools"       android:layout_width="match_parent"       android:layout_height="match_parent"       tools:context=".MainActivity" >          <com.example.zhy_event03.MyButton           android:id="@+id/id_btn"           android:layout_width="wrap_content"           android:layout_height="wrap_content"           android:text="click me" />      </LinearLayout>   最后看一眼MainActivity的代码

    [java]  view plain  copy package com.example.zhy_event03;      import android.app.Activity;   import android.os.Bundle;   import android.util.Log;   import android.view.MotionEvent;   import android.view.View;   import android.view.View.OnTouchListener;   import android.widget.Button;      public class MainActivity extends Activity   {       protected static final String TAG = "MyButton";       private MyButtonmButton ;       @Override       protected void onCreate(Bundle savedInstanceState)       {           super.onCreate(savedInstanceState);           setContentView(R.layout.activity_main);                      mButton = (MyButton) findViewById(R.id.id_btn);           mButton.setOnTouchListener(new OnTouchListener()           {               @Override               public boolean onTouch(View v, MotionEvent event)               {                   int action = event.getAction();                      switch (action)                   {                   case MotionEvent.ACTION_DOWN:                       Log.e(TAG, "onTouch ACTION_DOWN");                       break;                   case MotionEvent.ACTION_MOVE:                       Log.e(TAG, "onTouch ACTION_MOVE");                       break;                   case MotionEvent.ACTION_UP:                       Log.e(TAG, "onTouch ACTION_UP");                       break;                   default:                       break;                   }                                      return false;               }           });       }             }   在MainActivity中,我们还给MyButton设置了OnTouchListener这个监听~

    好了,跟View事件相关一般就这三个地方了,一个onTouchEvent,一个dispatchTouchEvent,一个setOnTouchListener;

    下面我们运行,然后点击按钮,查看日志输出:

    [html]  view plain  copy 08-31 06:09:39.030: E/MyButton(879): dispatchTouchEvent ACTION_DOWN   08-31 06:09:39.030: E/MyButton(879): onTouch ACTION_DOWN   08-31 06:09:39.049: E/MyButton(879): onTouchEvent ACTION_DOWN   08-31 06:09:39.138: E/MyButton(879): dispatchTouchEvent ACTION_MOVE   08-31 06:09:39.138: E/MyButton(879): onTouch ACTION_MOVE   08-31 06:09:39.147: E/MyButton(879): onTouchEvent ACTION_MOVE   08-31 06:09:39.232: E/MyButton(879): dispatchTouchEvent ACTION_UP   08-31 06:09:39.248: E/MyButton(879): onTouch ACTION_UP   08-31 06:09:39.248: E/MyButton(879): onTouchEvent ACTION_UP   我有意点击的时候蹭了一下,不然不会触发MOVE,手抖可能会打印一堆MOVE的日志~~~

    好了,可以看到,不管是DOWN,MOVE,UP都会按照下面的顺序执行:

    1、dispatchTouchEvent

    2、 setOnTouchListener的onTouch

    3、onTouchEvent

    下面就跟随日志的脚步开始源码的探索

    首先判断mOnTouchListener不为null,如果return true就不会有onTouchEvent事件了

    OnTouchListen>onTouchEvent>OnClickListen。点击事件是最后执行的

    总结整个View的事件转发流程是:

    View.dispatchEvent->View.setOnTouchListener->View.onTouchEvent

    在dispatchTouchEvent中会进行OnTouchListener的判断,如果OnTouchListener不为null且返回true,则表示事件被消费,onTouchEvent不会被执行;否则执行onTouchEvent到OnClickListen

    转载请注明原文地址: https://ju.6miu.com/read-21461.html

    最新回复(0)