zoukankan      html  css  js  c++  java
  • android菜鸟之路-事件分发机制总结(二)

    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事件将不会得到运行。

    到了这里我建议先结合两位大神的源代码看看吧


    看完以后再看看这张图,是不是瞬间明确了


    实在想不明确的朋友能够把我上面的代码拷过去。依据自己的想法改一改,然后执行执行,非常快你就会豁然开朗


    总结:当点击布局里的控件时。首先会调用ViewGroup的dispatchTouchEvent方法,假设onInterceptTouchEvent方法返回的是false,那么就会调用子View的dispatchTouchEvent方法(这种方法返回true就表示子View把事件消费掉了)。假设onInterceptTouchEvent方法返回的是true,那么就会调用ViewGroup的父类(也就是View)的dispatchTouchEvent方法,接下来调用布局的onTouch、onTouchEvent方法。

    能够这么记着:布局把事情交给子View处理,子View的dispatchTouchEvent方法返回true表示它把事情干完了,布局就不处理了。假设返回false,就是子View没处理完,那么布局就要处理了。

    (再回过头去看  ***切记那里,明确了么?朋友。假设一个事件你返回了false,后面的就是布局在处理了,所以子View后面的事件不会运行)

    好吧。我承认这篇写的有点水,事实上主要是提供代码给大家执行着试试。自己动手。丰衣足食。



  • 相关阅读:
    JavaScript 闭包
    JavaScript for循环
    JavaScript switch语句
    JavaScript if...else 语句
    JavaScript流程控制语句脑图
    JavaScript比较和逻辑运算符
    JavaScript运算符
    记录一下获取浏览器可视区域的大小的js
    20181016记录一次前端布局
    20181015记录一个简单的TXT日志类
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/7141868.html
Copyright © 2011-2022 走看看