Android系統中的每個ViewGroup的子類都具有下面三個和TouchEvent處理密切相關的方法:
public boolean dispatchTouchEvent(MotionEvent ev) // 這個方法用來分發TouchEvent
public boolean onInterceptTouchEvent(MotionEvent ev) //這個方法用來攔截TouchEvent
public boolean onTouchEvent(MotionEvent ev) //這個方法用來處理TouchEvent
注意:不是所有的View的子類,很多教程都說的是所有的View的子類,只有可以向裡面添加View的控件才需要分發,比如TextView它本身就是最小的view了,所以不用再向它的子視圖分發了,它也沒有子視圖了,所以它沒有dispatch和Intercept,只有touchEvent。
onInterceptTouchEvent(MotionEvent ev)方法是GroupView控件中特有的一個方法,我們可以實現這個方法來截獲所有的窗口點擊事件來根據事件的不同來對子控件或自身分發事件觸發。覆蓋這個方法時需要小心注意,因為它和View.onTouchEvent(MotionEvent)有著復雜的關系,我們使用是需要和View.onTouchEvent(MotionEvent)一同實現來達到正確的結果,事件觸發順序如下:
1.你首先會在該方法中得到一個down事件。
2.這個down事件會被得到處理,要麼在這個GroupView中子控件的onTouchEvent()方法中,要麼在GroupView自身的onTouchEvent()方法中。當我們在onTouchEvent()方法返回值中返回true的話,將會繼續看到後續的觸發事件(move、up等),要注意的是當我們在GroupView的onTouchEvent()事件返回值中返回false的話,該方法將不再捕獲後續的(move up)事件。
3.如果在該方法返回值中返回false,down事件將根據控件樹結構從根節點向目標子控件的onTouchEvent()方法分發。
4.如果在該方法返回值中返回true,那麼你的子控件將獲取不到任何點擊事件。
為證明上面所說的順序特點,下面通過測試代碼來觀察觀察:
復制代碼
public class MainActivity extends Activity {
Group1 group1;
Group2 group2;
MyTextView myTv;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//--group1
//----|
//-------group2
//---------|
//------------myTv
group1 = new Group1(this);
group2 = new Group2(this);
myTv = new MyTextView(this);
group2.addView(myTv, new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
group1.addView(group2, new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
setContentView(group1);
}
}