編輯:關於Android編程
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;
}
}
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);
}
}
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
Android進階(二十三)Android開發過程之實例講解
前言回過頭來審視之前做過的Android項目,發覺自己重新開發時忽然間不知所措了,間隔了太長時間沒有開發導致自己的Android技能知識急劇下降。溫故而知新。廢話少說,進
Android設備間實現藍牙(Bluetooth)共享上網
Android設備之間可以除了通過wifi熱點共享上網,還可以通過藍牙共享上網,後面這個功能很少人使用,但適合某台設備沒有wifi卻有藍牙的情況。一、設置WT19i,系統
Android提高UI性能技巧
提高UI性能的方法其實有很多在實際的開發中都已經用到了,在此做一下總結。 1.減少主線程的阻塞時間 若一個操作的耗時較長(超過5秒),我們應該將其放入後台線程中執行,只在
布局與控件(三)-TextView那些事兒
第3節 TextView這是界面設計最為常用的控件,也是很多別的控件的父類,例如Button。3.1 文字常用屬性最常使用到的屬性,通過它們的名字就可以判斷出它們的作用: