您好,登錄后才能下訂單哦!
1:View的事件響應機制(控件:如TextView,ImageView,Button等)
在執行onTouchListener方法時候,(view這里代表為控件)
view.setOnTouchListener (new OnTouchListener() {
@Override
public boolean onTouch( View v, MotionEvent event) {
return false ;
}
});
事件分發的時候會執行publicboolean dispatchTouchEvent(MotionEvent event)
a:先進行if判斷
if (li != null && li .mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
&& li .mOnTouchListener .onTouch (this, event)) {
return true ;
}
return onTouchEvent(event) ;
li就是OnTouchListener的實現類,不為null,第二個條件判斷控件是否可用,一般恒成立,主要就看第三個條件了。
return true:就代表響應所有事件。
return false:就會執行onTouchEvent方法了。
b:setOnTouchListener方法返回了false
在onTouchEvent方法中,如果控件具備點擊事件,在action_up中回調執行onClick的點擊事件,并且返回true,響應所有事件。如果控件不具備點擊事件,就會返回false,也進入不了switch中。
2:ViewGroup的事件響應機制
ViewGroup的事件響應機制主要分為2部分:1:ViewGroup攔截了事件,2:ViewGroup沒有攔截事件
/*
* return true 攔截了事件
* return false 沒有攔截事件,往內部傳遞
*/
@Override
public boolean onInterceptTouchEvent( MotionEvent ev) {
return true ;
}
1:攔截了事件:
那么ViewGroup就會去處理事件,在源碼中最后還是調用View的dispatchTouchEvent方法,由其決定是否響應,onTouchEventListener中return了true,就響應了事件,return了false,那么就去判斷當前控件(布局)是不是可以被點擊,測試了一次ListView,ListView點擊的時候響應了事件。ListView無論是不是中斷,都會由View的dispatchTouchEvent方法決定,ListView可以被點擊。
2:沒有攔截事件:
最外層的ViewGroup先捕獲到事件,計算出點擊的位置,遍歷自己的孩子,傳遞給對應的ViewGroup,然后第二層是不是攔截啊?不攔截,繼續遍歷,找到具體點擊的地方的控件view。
控件view會去通過View的dispatchTouchEvent方法的返回值判斷是不是響應了點擊事件,return true;響應了,那么結束了。如果return false;了沒有響應,那么事件會向回傳遞,自己的父親回去嘗試響應了。同樣,通過dispatchTouchEvent來進行決定是不是響應了事件。
示例代碼:
1:攔截事件
自定義控件
public class MyLinearLayout extends LinearLayout {
public MyLinearLayout (Context context , AttributeSet attrs ) {
super(context , attrs );
}
@Override
public boolean onInterceptTouchEvent( MotionEvent ev) {
return true ;
}
}
MainActivity
public class MainActivity extends Activity {
private LinearLayout my_ll;
private Button button;
private TextView textView;
@Override
protected void onCreate( Bundle savedInstanceState) {
super.onCreate (savedInstanceState );
setContentView (R .layout .activity_main);
my_ll = (LinearLayout ) findViewById (R .id .my_ll);
button = (Button ) findViewById (R .id .button);
textView = (TextView ) findViewById (R .id .text);
my_ll. setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch( View v, MotionEvent event) {
System .out.println( "Linearlayout:"+event .getAction ());
return true ;
}
});
textView. setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch( View v, MotionEvent event) {
System .out.println( "TextView:"+event .getAction ());
return false ;
}
});
button. setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch( View v, MotionEvent event) {
System .out.println( "Button:"+event .getAction ());
return false ;
}
});
// my_ll.setOnClickListener(new OnClickListener() {
//
// @Override
// public void onClick(View v) {
// System.out.println(" Linearlayout");
// }
// });
}
}
分析:my_ll不再向里面的Button和TextView傳遞了,自己處理,自己在my_ll.setOnTouchListener中返回了false,my_ll又不具備點擊事件,當然就只能打印出LineraLayout::0了,如果我們給其設置了點擊事件,那么當然會打印出down,up,click三者了。my_ll.setOnTouchListener中返回了true,自己也進行了處理,不過就只能打印出down,up了。
2:不攔截事件
分析:點擊button,響應了事件,其可以點擊,肯定會響應。點擊TextView時候,其默認沒有點擊事件,只能打印down了,然后不響應,往回傳遞,my_ll去響應,my_ll又會通過View的dispatchTouchEvent去處理了。我們這里在my_ll.setOnTouchListener中返回了true的話,肯定會打印如下:TextView的down,MyLinearlayout的down,up了。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。