ViewGroup事件分发机制
自己定义一个LinearLayout,ImageView和Button,小二,上代码
<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.aaaaa.MyLinear android:id="@+id/linear" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#956456" > <com.example.aaaaa.MyImage android:id="@+id/id_ll" android:layout_width="150dp" android:layout_height="150dp" android:src="@drawable/ic_launcher" android:text="click me" /> <com.example.aaaaa.MyButton android:id="@+id/id_btn" android:layout_width="150dp" android:layout_height="150dp" android:src="@drawable/ic_launcher" android:text="click me" /> </com.example.aaaaa.MyLinear> </LinearLayout>
public class MyLinear extends LinearLayout{ private static final String TAG =MyLinear.class.getSimpleName(); public MyLinear(Context context, AttributeSet attrs) { super(context, attrs); } public MyLinear(Context context) { super(context); } @Override public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "LinearLayout+onTouchEvent ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "LinearLayout+onTouchEvent ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.e(TAG, "LinearLayout+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, "LinearLayout+dispatchTouchEvent ACTION_DOWN"); // return true; break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "LinearLayout+dispatchTouchEvent ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.e(TAG, "LinearLayout+dispatchTouchEvent ACTION_UP"); break; default: break; } boolean a=super.dispatchTouchEvent(event); // Log.e(TAG, "LinearLayout:a="+a); return a; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return super.onInterceptTouchEvent(ev); } }
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, "button+onTouchEvent ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "button+onTouchEvent ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.e(TAG, "button+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, "button+dispatchTouchEvent ACTION_DOWN"); // return true; break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "button+dispatchTouchEvent ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.e(TAG, "button+dispatchTouchEvent ACTION_UP"); break; default: break; } boolean a=super.dispatchTouchEvent(event); // Log.e(TAG, "button:a="+a); return a; // return super.dispatchTouchEvent(event); } }
public class MyImage extends ImageView { private static final String TAG = MyImage.class.getSimpleName(); public MyImage(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"); return false; // 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; } boolean a=super.dispatchTouchEvent(event); // Log.e(TAG, "ImageView:a="+a); return a; // return super.dispatchTouchEvent(event); } }
public class MainActivity extends Activity { protected static final String TAG = "MainActivity"; private MyImage imageView; private MyButton button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageView=(MyImage) findViewById(R.id.id_ll); button=(MyButton) findViewById(R.id.id_btn); imageView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Log.e(TAG, "setOnClickListener000"); } }); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Log.e(TAG, "button+setOnClickListener000"); } }); final LinearLayout ll = (LinearLayout) findViewById(R.id.linear); // ll.setOnClickListener(new OnClickListener() { // @Override // public void onClick(View v) { // Log.e(TAG, "LinearLayout+setOnClickListener000"); // } // }); // ll.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "LinearLayout+onTouch ACTION_DOWN"); Log.e(TAG, "LinearLayout+000"+ll.isClickable()); // return false; break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "LinearLayout+onTouch ACTION_MOVE"); Log.e(TAG, "LinearLayout+000"+ll.isClickable()); // return false; break; case MotionEvent.ACTION_UP: Log.e(TAG, "LinearLayout+onTouch ACTION_UP"); Log.e(TAG, "LinearLayout+000"+ll.isClickable()); break; default: break; } return true; } }); imageView.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"); Log.e(TAG, "000"+imageView.isClickable()); // return false; break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "onTouch ACTION_MOVE"); Log.e(TAG, "000"+imageView.isClickable()); // return false; break; case MotionEvent.ACTION_UP: Log.e(TAG, "onTouch ACTION_UP"); Log.e(TAG, "000"+imageView.isClickable()); break; default: break; } return true; } }); button.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "button+onTouch ACTION_DOWN"); // Log.e(TAG, "button+000"+button.isClickable()); // return false; break; case MotionEvent.ACTION_MOVE: Log.e(TAG, "button+onTouch ACTION_MOVE"); // Log.e(TAG, "button+000"+button.isClickable()); // return false; break; case MotionEvent.ACTION_UP: Log.e(TAG, "button+onTouch ACTION_UP"); // Log.e(TAG, "button+000"+button.isClickable()); break; default: break; } return false; } }); } }
代码都很easy,基本都是信息打印,OK。那我们開始測试吧
假设轻轻点击自己定义Button,并手抖一下。会打印出什么信息呢?让我们来look一look
假设轻轻点击自己定义ImageView。并手抖一下,又会打印出什么信息呢?让我们来look一look
为什么会这样呢?
由于我在自己定义ImageView的dispatchTouchEvent方法里的MotionEvent.ACTION_DOWN事件推断里返回了false,还记得我们上一篇结尾说的么?
***切记,仅仅有每一个ACTION_DOWN。ACTION_MOVE,ACTION_UP事件相应的dispatchTouchEvent方法都返回true。才干依次往后运行,就是说假设dispatchTouchEvent方法里此时的event.getAction()==ACTION_DOWN,
你返回了false,那么后面的dispatchTouchEvent方法都不会运行(说白了,每一个动作事件都会运行一次dispatchTouchEvent,运行ACTION_DOWN的时候返回了false,后面一系列其他的action就不会再得到运行了,也就是ACTION_MOVE,ACTION_UP事件将不会得到运行。
到了这里我建议先结合两位大神的源代码看看吧
http://blog.csdn.net/guolin_blog/article/details/9153747
http://blog.csdn.net/lmj623565791/article/details/39102591
看完以后再看看这张图,是不是瞬间明确了
实在想不明确的朋友能够把我上面的代码拷过去。依据自己的想法改一改,然后执行执行,非常快你就会豁然开朗