編輯:關於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設備之間可以除了通過wifi熱點共享上網,還可以通過藍牙共享上網,後面這個功能很少人使用,但適合某台設備沒有wifi卻有藍牙的情況。一、設置WT19i,系統
提高UI性能的方法其實有很多在實際的開發中都已經用到了,在此做一下總結。 1.減少主線程的阻塞時間 若一個操作的耗時較長(超過5秒),我們應該將其放入後台線程中執行,只在
第3節 TextView這是界面設計最為常用的控件,也是很多別的控件的父類,例如Button。3.1 文字常用屬性最常使用到的屬性,通過它們的名字就可以判斷出它們的作用: