android 事件傳遞機制(1),android傳遞

來源:互聯網
上載者:User

android 事件傳遞機制(1),android傳遞

 

在項目中,經常遇到事件衝突,ScrollView,ViewPager滑動卡頓等情況,比如:onClick和onLongClick事件衝突,dispatchTouchEvent,onInterceptTouchEvent這些方法都有一個boolean傳回值,不同傳回值事件處理機制是不同的。

一:事件分發流程

1:現在有一個情境,使用者長按button,我們希望只觸發onLongClick,然而onClick事件也觸發了.

這種情況比如簡單,直接在onLongClick返回true就可以解決了,返回true表示onLongClick消費了這次事件。

2:view 和 viewGroup的介紹

View是所有UI組件的基類(如:TextView,Button,ImageView),而 ViewGroup是容納這些組件的容器(如:LinearLayout,ReltiveLayout),ViewGroup是View派生出來的.

view有dispatchTouchEvent,onTouchEvent這兩個方法,ViewGroup多了一個onInterceptTouchEvent方法,此方法決定觸發事件是自己處理,還是分發給下一個組件處理.

2:事件涉及到的常用方法

使用者點擊螢幕時,將觸發viewGroup的dispatchTouchEvent(MotionEvent ev)、onInterceptTouchEvent(MotionEvent ev)、onTouchEvent(MotionEvent ev);

3:方法傳回值介紹

dispatchTouchEvent是處理觸摸事件分發,事件(多數情況)是從Activity的dispatchTouchEvent開始的。執行super.dispatchTouchEvent(ev),事件向下分發。

onInterceptTouchEvent是ViewGroup提供的方法,預設返回false,返回true表示攔截,返回true後,由該類的onTouchEvent方法來執行

onTouchEvent是View中提供的方法,ViewGroup也有這個方法,view中不提供onInterceptTouchEvent。view中預設返回true,表示消費了這個事件。

二:舉一個栗子

1  老闆將一個任務分配給經理,經理將任務分配給員工去完成,員工完成後,將結果反饋給經理,經理將任務結果反饋給老闆,這是預設流程。

 

預設流程dispatchTouchEvent(MotionEvent ev)、onInterceptTouchEvent(MotionEvent ev)、onTouchEvent(MotionEvent ev),全部返回super.xxxxxxx
        

 

輸出日誌的結果

10-15 20:13:31.600 8716-8716/com.activity E/info: BossView  dispatchTouchEvent()   boss create task!10-15 20:13:31.600 8716-8716/com.activity E/info: BossView  onInterceptTouchEvent()  boss將task 分配給manager10-15 20:13:31.600 8716-8716/com.activity I/info: ManagerView  經理讓onInterceptTouchEvent決定任務由誰完成10-15 20:13:31.600 8716-8716/com.activity I/info: ManagerView  onInterceptTouchEvent()經理接收到任務,將任務分配給員工10-15 20:13:31.601 8716-8716/com.activity I/info: EmployeesView 員工開始工作.10-15 20:13:31.601 8716-8716/com.activity I/info: EmployeesView 員工圓滿完成任務.10-15 20:13:31.602 8716-8716/com.activity I/info: ManagerView   onTouchEvent() 經理驗收任務結果,並向老闆報告10-15 20:13:31.602 8716-8716/com.activity E/info: BossView  onTouchEvent()   工作已經完畢

 

2  老闆將一個任務分配給經理,經理將任務分配給員工去完成,員工覺得難度大,無法完成(onTouchEvent返回true),由於老闆沒有接收到工作報告,會不停向經理分發任務(managerView的dispatchTouchEvent方法將不停被調用,員工的dispatchTouchEvent方法也會被繼續調用)。

輸出日誌:

3  老闆將一個任務分配給經理,因為上一次任務,經理並未收到員工的工作報告,所以這次經理決定,自己的來本次完成,將事件直接消費(onInterceptTouchEvent返回true),不分給員工去做,讓員工一邊涼快去 。

日誌輸出:

10-15 22:11:26.877 22219-22219/com.activity I/info: MainActivity--dispatchTouchEvent()ACTION_DOWN10-15 22:11:26.878 22219-22219/com.activity E/info: BossView  dispatchTouchEvent()   boss create task!10-15 22:11:26.879 22219-22219/com.activity E/info: BossView  onInterceptTouchEvent()  boss將task 分配給manager10-15 22:11:26.879 22219-22219/com.activity I/info: ManagerView  經理讓onInterceptTouchEvent決定任務由誰完成10-15 22:11:26.879 22219-22219/com.activity I/info: ManagerView  onInterceptTouchEvent()經理接收到任務安排,員工做得不好,自己來做任務10-15 22:11:26.879 22219-22219/com.activity I/info: ManagerView   onTouchEvent() 經理驗收任務結果,並向老闆報告10-15 22:11:26.879 22219-22219/com.activity E/info: BossView  onTouchEvent()   工作已經完畢10-15 22:11:26.886 22219-22219/com.activity I/info: MainActivity--dispatchTouchEvent()ACTION_MOVE10-15 22:11:26.902 22219-22219/com.activity I/info: MainActivity--dispatchTouchEvent()ACTION_MOVE10-15 22:11:26.912 22219-22219/com.activity I/info: MainActivity--dispatchTouchEvent()ACTION_MOVE10-15 22:11:26.919 22219-22219/com.activity I/info: MainActivity--dispatchTouchEvent()ACTION_MOVE10-15 22:11:26.921 22219-22219/com.activity I/info: MainActivity--dispatchTouchEvent()ACTION_UP

三:代碼

由於代碼差不多,這裡只貼出ManagerView的代碼,完整代碼下載串連在文章下方

public class ManagerView extends LinearLayout {
private final String TAG="ManagerView ";
private int index=0;
public ManagerView(Context context) {
super(context);
}

public ManagerView(Context context, AttributeSet attrs) {
super(context, attrs);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
if(index==0){
Log.i("info",TAG+" onTouchEvent() 經理驗收任務結果,並向老闆報告");
}else{
Log.i("info",TAG+" onTouchEvent() 自己親自來完成任務");
}
return super.onTouchEvent(event);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
index = 0;
// if(index==0){
// Log.i("info",TAG+"onInterceptTouchEvent()經理接收到任務,將任務分配給員工");
// return super.onInterceptTouchEvent(ev);
// }else{
Log.i("info",TAG+"onInterceptTouchEvent()經理接收到任務安排,員工做得不好,自己來做任務");
return true;
// }

}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.i("info",TAG+"經理讓onInterceptTouchEvent決定任務由誰完成");
return super.dispatchTouchEvent(ev);
}
}

 

 

備忘:上傳代碼時,我電腦github出了點小問題,如果代碼有問題,請留言,代碼:github

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.