Android Viewイベント配信

3701 ワード

1、本文の主な内容はviewのイベント配布を詳しく分析することであり、viewのはView Groupに比べて簡単である.
1.1 onTouchListener onTouch onClickListenerがある場合onTouchListenerがfalseログに戻る
09-11 08:01:47.864 6507-6507/? I/Tag: view -> onTouch ->0
09-11 08:01:47.864 6507-6507/? I/Tag: view -> onTouchEvent ->0
09-11 08:01:47.975 6507-6507/? I/Tag: view -> onTouch ->2
09-11 08:01:47.975 6507-6507/? I/Tag: view -> onTouchEvent ->2
09-11 08:01:48.088 6507-6507/? I/Tag: view -> onTouch ->1
09-11 08:01:48.088 6507-6507/? I/Tag: view -> onTouchEvent ->1
09-11 08:01:48.090 6507-6507/? I/Tag: view -> onClick

1.2 onTouchListener onTouch onClickListenerの場合onTouchListenerがtrueログに戻る
09-11 08:19:03.021 7029-7029/? I/Tag: view -> onTouch ->0
09-11 08:19:03.174 7029-7029/? I/Tag: view -> onTouch ->2
09-11 08:19:03.459 7029-7029/? I/Tag: view -> onTouch ->1

1.3 onTouchListener onClickListenerがある場合onTouchListenerがtrueログに戻る
09-11 08:31:31.400 7620-7620/? I/Tag: view -> onTouch ->0
09-11 08:31:31.441 7620-7620/? I/Tag: view -> onTouch ->2
09-11 08:31:31.667 7620-7620/? I/Tag: view -> onTouch ->1

2、次にソースコードを分析する
2.1 viewのソースコードdispatchTouchEvent(MotionEvent event)を見つけるこの方法すべてのviewとView Groupのイベント配布と応答はここから始まる可能性のある異なるsdkバージョンのソースコードに少し違いがあります私はここで7.1.1です
以下の出現コードはすべて重点的に注目する必要がある他のものは注目しなくてもよい.
boolean result=falseこれはdispatchTouchEventの戻り値です
ListenerInfo li = mListenerInfo;
このListenerInfoは、実はView全体にわたってすべてのインタフェースが格納されている場所です.
最も重要な2つの方法の1つです

if (li != null && li.mOnTouchListener != null
                    && (mViewFlags & ENABLED_MASK) == ENABLED
                    && li.mOnTouchListener.onTouch(this, event)) {
                result = true;
    }

ここでliはすでに値を割り当てて空に等しいはずがない.
mOnTouchListenerこの方法はあなたがインタフェースを実現したかどうかです.こちらも空いていません.
(mViewFlags&ENABLED_MASK)==ENABLEDこれはあなたのviewが利用できるかどうか、つまりクリックできるかどうかは一般的にデフォルトでは利用可能ですここもtrueです
li.mOnTouchListener.onTouch(this,event)という方法が実現の方法である
なぜonTouchが最初に呼び出されたのかもその理由ですここでは1.1の場合falseを返します
だからresult=true;このif判断は入らない
if (!result && onTouchEvent(event)) {
                result = true;
    }

上ifでresultかfalse onTouchEventか判断したのでここでonTouchEventのメソッドを呼び出します
ここでonTouchEventの内部を見てみましょうデフォルトでsuperに戻るとします.onTouchEvent(event)ここではtrueを返します
この方法ではperformClick()という方法が見えます.これはイベントをクリックすることです.中に入ってみましょう.
 if (!post(mPerformClick)) {
   performClick();
}
......
public boolean performClick() {
        final boolean result;
        final ListenerInfo li = mListenerInfo;
        if (li != null && li.mOnClickListener != null) {
            playSoundEffect(SoundEffectConstants.CLICK);
            li.mOnClickListener.onClick(this);//    onClick      
            result = true;
        } else {
            result = false;
        }

        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
        return result;
}


3ソースコードを見た後、私たちは上記の3つの状況の結論を出すことができます.
3.1第1種全てがデフォルト実装の場合はまずdispatchTouchEventの中で最初のif判定のliに進む.mOnTouchListener.onTouch(this,event)、次に2番目のif判断onTouchEvent(event)という方法で最後にonTouchEventのperformClick()を歩いてviewのイベントフローを完成しました
3.2第2のonTouchListenerの戻り値はtrueです.ソースコードを見たばかりで、liも知っています.mOnTouchListener.onTouch(this,event)の戻り値がtrueであることは、最初のif判定がresult=trueであることを示す.これで2番目のifが入らないと判断して3つのonTouchしか現れません
3.3第3種onTouchEventはtrueを返すここでsuperは呼び出さない.onTouchEvent(event)だから親のperformClick()メソッドを実行しないのでonClick印刷は現れません
4、ここではresultが戻ってくる理由にかかわらず、このコードの流れに注目すればいいのですが、次の節ではViewGroupのイベント配布でこのresultが戻ってくる値の使い道について言及します