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)を設定します.