View的事件分发:
1、 触摸事件的传递流程是从dispatchTouchEvent开始的,如果不进行人为干预(super.dispatchTouchEvent()),则事件会按照嵌套层次从外层依次向内层传递,到达最内层View时,就由它的TouchEvent方法处理。该方法如果能消费此事件,则返回true,如果处理不了,则返回false,这时事件会重新向外层传递,并由外层view的touchevetnt方法进行处理,以此类推。如果进行人为干预,无论返回true或false,都不再向下传递。
2、 如果事件在向内层传递过程中进行人为干预,处理函数返回true,则会导致事件提前被消费掉,内层view将不会收到此事件
3、 View控件的事件触发顺序是先执行onTouch方法,在最后才执行onClick方法。如果OnTouch返回true,则事件不会继续传递,最后也不会调用onclick方法,如果onTouch返回false,则事件继续传递。
package com.lantier.xxb_student.firstapp; import android.content.Context; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.widget.TextView; /** * Created by xxb_student on 2017/6/7. */ public class MyTextView extends TextView { private static final String TAG = "MyTextView"; 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 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; } return true; } @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; } return super.dispatchTouchEvent(event); }}
package com.lantier.xxb_student.firstapp; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.MotionEvent; import android.view.View; public class TouchActivity extends AppCompatActivity implements View.OnTouchListener, View.OnClickListener{ private static final String TAG = "TouchActivity"; private MyTextView tvTest; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_touch); initView(); } private void initView() { tvTest = (MyTextView) findViewById(R.id.tv_test); tvTest.setOnClickListener(this); tvTest.setOnTouchListener(this); } @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; } return super.onTouchEvent(event); } @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; } return super.dispatchTouchEvent(event); } @Override public boolean onTouch(View v, MotionEvent event) { switch (v.getId()){ case R.id.tv_test: switch (event.getAction()){ case MotionEvent.ACTION_DOWN: Log.e(TAG, "---->>tv_test onTouch ACTION_DOWN: " ); break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "---->>tv_test onTouch ACTION_MOVE: " ); break; case MotionEvent.ACTION_UP: Log.e(TAG, "---->>tv_test onTouch ACTION_UP: " ); break; } break; } return false; } @Override public void onClick(View v) { switch (v.getId()){ case R.id.tv_test: Log.e(TAG, "---->>onClick:tv_test " ); break; } } }
<?xml version="1.0" encoding="utf-8"?> <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="com.lantier.xxb_student.firstapp.TouchActivity"> <com.lantier.xxb_student.firstapp.MyTextView android:id="@+id/tv_test" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="自定义TextView"/> </LinearLayout>