Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android事件分發詳解(五)——Touch事件傳遞驗證

Android事件分發詳解(五)——Touch事件傳遞驗證

編輯:關於Android編程

MainActivity如下:
package cn.c;
import android.os.Bundle;
import android.app.Activity;
import android.view.MotionEvent;

/**
 * Demo描述:
 * 分析Android事件分發和處理機制
 * 
 * 
 * 總結:
 * 1 ViewGroup繼承自View
 *   事件的傳遞方向為:從最外層(Activity)傳遞至最內層(某個View)
 *   事件的消費方向為:從最內層(某個View)傳遞至最外層(Activity)
 *   該兩個方向是相反的
 * 2 ViewGroup中事件處理的流程是:
 *   dispatchTouchEvent->onInterceptTouchEvent->onTouchEvent
 *   View中事件處理的流程是:
 *   dispatchTouchEvent->onTouchEvent
 * 3 ViewGroup中onInterceptTouchEvent默認值是false
 *   表示未攔截
 *   ViewGroup中onTouchEvent默認值是false
 *   表示未消費
 *   View中onTouchEvent返回默認值是true
 *   表示已消費
 *   
 *   小結:
 *   (1) 每一次的ACTION_DOWN和ACTION_MOVE以及ACTION_UP都會引起每一層的dispatchTouchEvent()
 *       所以:dispatchTouchEvent()的順序是由上至下的!!!!!!!!!!!!!!!
 *   (2) 但是每一層的onTouchEvent()就不一定會執行了.比如下層已經消耗掉了事件,那麼上層就不會響應onTouchEvent()了.
 *       所以:onTouchEvent()是從下到上回溯的.當然前提是事件沒有被消費的情況下!!!!!!!!!!!!!
 * 
 * 在該示例中涉及到三個自定義的View.分別是:
 * 最外層的布局MyFrameLayout
 * 內層的布局MyLinearLayout
 * 最裡層的自定義按鈕MyButton
 * 
 * 現在進行一系列的測試並對現象進行解釋
 * 
 * 測試一:
 * 在MyFrameLayout的dispatchTouchEvent()方法中直接返回false.
 * 那麼可以看到MyFrameLayout的onInterceptTouchEvent()和onTouchEvent()都沒有執行.
 * MyFrameLayout所包含的子View對於Touch事件也當然沒有任何的反映.
 * 其實這樣直接返回false是挺殘暴的.因為重寫了該方法,使得源碼中dispatchTouchEvent()方法裡的
 * 一大堆代碼都沒有執行,所以它的onInterceptTouchEvent()和onTouchEvent()都沒有調用也就沒有
 * 什麼事件的繼續分發了.
 * 因為它直接給Activity返回了false即連ACTION_DOWN事件都沒有處理.所以後續的事件比如ACTION_DOWN和ACTION_UP
 * 都沒有資格處理,都是直接由Activity處理了.
 * 
 * 
 * 測試二:
 * 在MyFrameLayout的dispatchTouchEvent()方法中調用:super.dispatchTouchEvent(ev);
 * 且返回return super.dispatchTouchEvent(ev);
 * 在MyFrameLayout的onInterceptTouchEvent()方法中直接返回return true;表示攔截
 * 可以看到事件的分發到了MyFrameLayout就停止了,不會向其子View派發.
 * 
 * 其余的驗證將在下一個例子中給出.
 * 
 */

public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        System.out.println(===> MainActivity 中調用 onCreate());
        System.out.println(--------------------------------------------------);
    }
	
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
    	System.out.println(===> MainActivity 中調用 dispatchTouchEvent());
		System.out.println(===> super.dispatchTouchEvent()默認返回true);
		System.out.println(--------------------------------------------------);
    	return super.dispatchTouchEvent(ev);
    }

	@Override
	public void onUserInteraction() {
		System.out.println(===> MainActivity 中調用 onUserInteraction());
		System.out.println(--------------------------------------------------);
		super.onUserInteraction();
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			System.out.println(===> MainActivity 中調用  onTouchEvent()--->ACTION_DOWN);
			break;
		case MotionEvent.ACTION_MOVE:
			System.out.println(===> MainActivity 中調用  onTouchEvent()--->ACTION_MOVE);
			break;
		case MotionEvent.ACTION_UP:
			System.out.println(===> MainActivity 中調用  onTouchEvent()--->ACTION_UP);
		default:
			break;
		}
		System.out.println(super.onTouchEvent()默認返回false 表示未消費事件);
		System.out.println(--------------------------------------------------);
		return super.onTouchEvent(event);
	}
	
}

 

MyFrameLayout如下:

package cn.c;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.FrameLayout;

public class MyFrameLayout extends FrameLayout{
	public MyFrameLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
	}
	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		super.dispatchTouchEvent(ev);
		System.out.println(外層MyFrameLayout 中調用  dispatchTouchEvent());
		System.out.println(super.dispatchTouchEvent()默認返回true 表示繼續分發);
		System.out.println(--------------------------------------------------);
		return super.dispatchTouchEvent(ev);
		//return false;
	}
	
	//覆寫自ViewGroup
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		System.out.println(外層MyFrameLayout 中調用  onInterceptTouchEvent());
		System.out.println(super.onInterceptTouchEvent()默認返回false 表示不攔截);
		System.out.println(--------------------------------------------------);
		//return super.onInterceptTouchEvent(ev);
		return true;
	}
	//注意:
	//1 ViewGroup是View的子類
	//2 ViewGroup中onTouchEvent()方法默認返回的是false
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		super.onTouchEvent(event);
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			System.out.println(外層MyFrameLayout 中調用  onTouchEvent()--->ACTION_DOWN);
			break;
		case MotionEvent.ACTION_MOVE:
			System.out.println(外層MyFrameLayout 中調用  onTouchEvent()--->ACTION_MOVE);
			break;
		case MotionEvent.ACTION_UP:
			System.out.println(外層MyFrameLayout 中調用  onTouchEvent()--->ACTION_UP);
		default:
			break;
		}
		System.out.println(super.onTouchEvent()默認返回false 表示未消費事件);
		System.out.println(--------------------------------------------------);
		return super.onTouchEvent(event);
		//return true;
	}
	
	

}

MyLinearLayout如下:
package cn.c;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.LinearLayout;

public class MyLinearLayout extends LinearLayout {
	public MyLinearLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
	}
	
	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		super.dispatchTouchEvent(ev);
		System.out.println(內層MyLinearLayout 中調用  dispatchTouchEvent());
		System.out.println(super.dispatchTouchEvent()默認返回true 表示繼續分發);
		System.out.println(--------------------------------------------------);
		//return super.dispatchTouchEvent(ev);
		return false;
	}
	
	//覆寫自ViewGroup
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		super.onInterceptTouchEvent(ev);
		System.out.println(內層MyLinearLayout 中調用  onInterceptTouchEvent());
		System.out.println(super.onInterceptTouchEvent()默認返回false 表示不攔截);
		System.out.println(--------------------------------------------------);
		return super.onInterceptTouchEvent(ev);
		
	}
	//注意:
	//1 ViewGroup是View的子類
	//2 ViewGroup中onTouchEvent()方法默認返回的是false
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			System.out.println(內層MyLinearLayout 中調用  onTouchEvent()--->ACTION_DOWN);
			break;
		case MotionEvent.ACTION_MOVE:
			System.out.println(內層MyLinearLayout 中調用  onTouchEvent()--->ACTION_MOVE);
			break;
		case MotionEvent.ACTION_UP:
			System.out.println(內層MyLinearLayout 中調用  onTouchEvent()--->ACTION_UP);
		default:
			break;
		}
		System.out.println(super.onTouchEvent()默認返回false 表示未消費事件);
		System.out.println(--------------------------------------------------);
		return super.onTouchEvent(event);
	}
	
	

}

MyButton如下:
package cn.c;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.Button;

public class MyButton extends Button{
	public MyButton(Context context, AttributeSet attrs) {
		super(context, attrs);
	}
	
	@Override
	public boolean dispatchTouchEvent(MotionEvent event) {
		System.out.println(自定義Button 中調用 dispatchTouchEvent());
		System.out.println(super.dispatchTouchEvent默認返回true);
		System.out.println(--------------------------------------------------);
		return super.dispatchTouchEvent(event);
	}
	
	//注意:
	//在View的子類中onTouchEvent()方法默認返回的是true
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			System.out.println(自定義Button 中調用 onTouchEvent()--->ACTION_DOWN);
			break;
		case MotionEvent.ACTION_MOVE:
			System.out.println(自定義Button 中調用 onTouchEvent()--->ACTION_MOVE);
			break;
		case MotionEvent.ACTION_UP:
			System.out.println(自定義Button 中調用 onTouchEvent()--->ACTION_UP);
			break;
		default:
			break;
		}
		System.out.println(super.onTouchEvent()默認返回true);
		System.out.println(--------------------------------------------------);
		return super.onTouchEvent(event);
	}
	
	
}



上一篇/kf/201412/365604.html
    
		   
    



 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved