觸控[0] 觸控事件傳遞機制
【參考連結】
開發藝術探索
1.
涉及到的類和方法主要有
ViewGroup的dispatchTouchEvent()、onInterceptTouchEvent()、onTouchEvent()
View的dispatchTouchEvent()、onInterceptTouchEvent()、onTouchEvent()
一般來說,在自定義View/ViewGroup的時候,不修改dispatchTouchEvent(),只重寫onInterceptTouchEvent()(不保留super呼叫)和onTouchEvent()(保留super呼叫,如果需要響應OnLongClickListener/OnClickListener
2.
如果設定了OnTouchListener,則會先執行OnTouchListener。並且只有OnTouchListener返回false才會再執行onTouchEvent()。
3.
如果子View能夠收到ACTION_DOWN但其OnTouchListener/onTouchEvent()返回了false,則其不會再收到後續的ACTION_MOVE、ACTION_UP等。
4.
可以在子View/ViewGroup的OnTouchListener/onTouchEvent()的ACTION_DOWN中使用getParent().requestDisallowInterceptTouchEvent()
注意這隻有在子View/ViewGroup能夠收到ACTION_DOWN的前提下才能起作用。
5、
只有能夠執行到View的super.onTouchEvent()才能夠觸發onLongClickListener/onClickListener。
如果設定了onLongClickListener,在ACTION_DOWN超時後就會觸發onLongClickListener。
只有當onLongClickListener返回false
可以使用如下的程式碼來修改驗證
public class
MyFrameLayout
extends
FrameLayout {
//public static final intACTION_DOWN = 0;
//public static finalint ACTION_UP = 1;
//public static finalint ACTION_MOVE = 2;
//public static finalint ACTION_CANCEL = 3;
public static final
String[]
ACTIONS={"ACTION_DOWN",
"ACTION_UP",
"ACTION_MOVE",
"ACTION_CANCEL"};
public MyFrameLayout(Context context)
{
super(context);
init();
}
public
MyFrameLayout(Context context,
AttributeSet attrs) {
super(context,
attrs);
init();
}
public
MyFrameLayout(Context context,
AttributeSet attrs, int
defStyle) {
super(context,
attrs,
defStyle);
init();
}
public void
init(){
setOnTouchListener(new
OnTouchListener() {
@Override
public boolean
onTouch(View view,
MotionEvent motionEvent) {
Log.e("shadowfaxghh",
"MyFrameLayout OnTouchListener "+ACTIONS[motionEvent.getAction()]);
return false;
}
});
setOnLongClickListener(new
OnLongClickListener() {
@Override
public boolean
onLongClick(View view) {
Log.e("shadowfaxghh",
"MyFrameLayout onLongClick");
return false;
}
});
setOnClickListener(new
OnClickListener() {
@Override
public void
onClick(View view) {
Log.e("shadowfaxghh",
"MyFrameLayout onClick");
}
});
}
@Override
public boolean
dispatchTouchEvent(MotionEvent ev) {
Log.e("shadowfaxghh",
"MyFrameLayout dispatchTouchEvent "+ACTIONS[ev.getAction()]);
return super.dispatchTouchEvent(ev);
}
@Override
public boolean
onInterceptTouchEvent(MotionEvent ev) {
Log.e("shadowfaxghh",
"MyFrameLayout onInterceptTouchEvent "+ACTIONS[ev.getAction()]);
//return super.onInterceptTouchEvent(ev);
//return false;
switch
(ev.getAction()){
case
MotionEvent.ACTION_DOWN:
return false;
default:
return true;
}
}
@Override
public boolean
onTouchEvent(MotionEvent event) {
Log.e("shadowfaxghh",
"MyFrameLayout onTouchEvent "+ACTIONS[event.getAction()]);
super.onTouchEvent(event);//for
onLongClick/onClick
return true;
}
}
public class
MyTextView
extends
TextView {
public static final
String[]
ACTIONS={"ACTION_DOWN",
"ACTION_UP",
"ACTION_MOVE",
"ACTION_CANCEL"};
public MyTextView(Context context)
{
super(context);
init();
}
public
MyTextView(Context context,
AttributeSet attrs) {
super(context,
attrs);
init();
}
public
MyTextView(Context context,
AttributeSet attrs, int
defStyle) {
super(context,
attrs,
defStyle);
init();
}
public void
init(){
setOnTouchListener(new
OnTouchListener() {
@Override
public boolean
onTouch(View view,
MotionEvent motionEvent) {
Log.e("shadowfaxghh",
"MyTextView OnTouchListener "+ACTIONS[motionEvent.getAction()]);
return false;
}
});
setOnLongClickListener(new
OnLongClickListener() {
@Override
public boolean
onLongClick(View view) {
Log.e("shadowfaxghh",
"MyTextView onLongClick");
return false;
}
});
setOnClickListener(new
OnClickListener() {
@Override
public void
onClick(View view) {
Log.e("shadowfaxghh",
"MyTextView onClick");
}
});
}
@Override
public boolean
dispatchTouchEvent(MotionEvent ev) {
Log.e("shadowfaxghh",
"MyTextView dispatchTouchEvent");
return super.dispatchTouchEvent(ev);
}
//@Override
//public booleanonInterceptTouchEvent(MotionEvent ev) {
//
//Log.e("shadowfaxghh", "MyTextViewonInterceptTouchEvent");
//
////return super.onInterceptTouchEvent(ev);
//return false;
//}
@Override
public boolean
onTouchEvent(MotionEvent event) {
Log.e("shadowfaxghh",
"MyTextView onTouchEvent "+ACTIONS[event.getAction()]);
super.onTouchEvent(event);//for
onLongClick/onClick
switch(event.getAction()){
case
MotionEvent.ACTION_DOWN:
getParent().requestDisallowInterceptTouchEvent(true);
break;
default:
break;
}
return true;
}
}