viewのイベント配信のonTouchとonClick
3302 ワード
Androidイベント配信
viewのイベント配信のonTouchとonClick
プロジェクトでは、1つのコントロールに対して2つのメソッドsetOnClickListenerとsetOnTouchListenerを書き換えて、このコントロールのクリックイベントと動作を傍受することがよくありますが、1つのコントロールの2つのメソッドを同時に傍受すると、どのように実行されますか?
->まず、Buttonなどのデフォルトでクリックできるコントロールを分析します.私たちはactivityにButtonコントロールを置いて、リスニングを設定します.
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e(tag, "onClick");
}
});
button.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.i(tag, "viewbutton-onTouch-ACTION_DOWN...");
break;
case MotionEvent.ACTION_UP:
Log.i(tag, "viewbutton-onTouch-ACTION_UP...");
break;
default:
break;
}
return false;
}
}
);
このコントロールをクリックすると、onTouchが先に実行し、onClickが実行され、onTouchがtrueに戻るとonClickのみが実行されます.dispatchTouchEventソースから
if (onFilterTouchEventForSecurity(event)) {
//noinspection SimplifiableIfStatement
ListenerInfo li = mListenerInfo;
if (li != null &&
//
li.mOnTouchListener != null
// enable true
&& (mViewFlags & ENABLED_MASK) == ENABLED
//
&& li.mOnTouchListener.onTouch(this, event)) {
result = true;
}
if (!result && onTouchEvent(event)) {
result = true;
}
}
私が表記した箇所で先に実行する、すなわちonTouch(this,event)は、trueを返すと次の判断条件は実行されず、onTouchEvent(event)は実行されません.しかし、なぜonClickを実行しないのでしょうか.onTouchEvent(event)のソースコードを確認すると
if (mPerformClick == null) {
mPerformClick = new PerformClick();
}
if (!post(mPerformClick)) {
performClick();
}
performClick()には、次のものがあります.
if (li != null && li.mOnClickListener != null) {
playSoundEffect(SoundEffectConstants.CLICK);
li.mOnClickListener.onClick(this);
result = true;
} else {
result = false;
}
onClickを実行します.そこで我々のプロセスは,まずコントロールのdispatchTouchEvent()を呼び出し,onTouch()を実行し,onTouch()がfalseに戻ると,コントロールのonTouchEventメソッドを実行し,onClickメソッドを実行する.
->ImageViewのように、デフォルトでクリックできないイベントを分析します.実行順序は上記と同じですが、onTouchEventメソッドでは、次のような判断条件があります.
if (((viewFlags & CLICKABLE) == CLICKABLE ||
(viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) ||
(viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE) {
まず判断するときにクリックして、できなければ入らず、その後onClickメソッドは実行されません.このビューでクリックイベントを実行させるにはsetClickable(true)を設定します.