Androidイベント配信メカニズムの研究

2549 ワード

ずっとandroidの事件の配布のメカニズムに対してとても困惑して、最近また再びこの知識を見て、自分に協力して小さいdemoを書いて、logを打って研究して、読書のノートをして、忘れて、もし間違いがあれば、批判の指摘を歓迎します.
結論1:親コンテナにこのように書く場合:
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return true;
}

onInterceptTouchEventは、タッチイベントをブロックするかどうかを示し、trueを返すと、その内のサブコントロールのタッチイベント、onClickイベントは実行されません.ただし、親コントロールのイベント配信には、View Groupのr e q u s t D e a l l o w InterceptTouchEventメソッドで関与することができる.例えば、ViewPagerは左右のスライド切替tabを実現し、tabのいずれかに水平スライド可能なViewが埋め込まれている場合、例えばtab項目の水平スライド可能なコントロールをスライドさせたいが、tab切替を招く.tabページにviewpagerインスタンスを注入し、onTouchイベントで処理できます.
public boolean onTouch(View v, MotionEvent event) {
    switch (event.getAction()) {
    case MotionEvent.ACTION_MOVE:
        pager.requestDisallowInterceptTouchEvent(true);
        break;
    case MotionEvent.ACTION_UP:
    case MotionEvent.ACTION_CANCEL:
        pager.requestDisallowInterceptTouchEvent(false);
        break;
    }
}

結論2:1つのタッチイベントが1つのコントロールに伝達されると、そのdispatchTouchEventが呼び出され、親コントロールのonInterceptTouchEventがfalseに戻る前提の下で、サブコントロールdispatchTouchEventがtrueを返し、そのサブコントロール自身がタッチイベントを消費することを表す(onTouchListenerが実行され、もしあれば)、すなわち,タッチイベントは親コントロールによって処理されず,親コントロールのonTouchListenerとonTouchEventメソッドはいずれも進まない.
結論3:タッチイベントの配布は上から下へ配布され,Activity->Window->View.ビューの間でも上から下へ配布されており、タッチイベントが親コンテナに到着すると、親コンテナが子ビューに下へ配布される.したがって,タッチイベントに応答して実行する順序が逆になり,サブViewから処理が開始され,サブviewのdispatchTouchEventメソッドがfalseを返すと親コンテナ処理に渡される(親コンテナのonTouchListenerが呼び出される).注意このとき、サブビューのonTouchListenerとonTouchEvent(onTouchListenerがfalseに戻る場合)イベントは依然として呼び出されますが、調整が完了すると親コントロールに呼び出され、親コンテナのdispatchTouchEventメソッドもfalseに戻ると、dispatchTouchEventが戻ってfalseに戻ると、ActivityのonTouchEventが落ちます.
結論4:onTouchListenerメソッドはイベント配布中の優先度が最も高く、viewがonTouchListenerメソッドを設定しtrueを返し、イベントが消費されたことを表す場合、彼のonTouchEventメソッドは行けない.注意:私は任大神の本を読んで、もし子ViewのonTouchEvent方法がfalseに戻ると、親コンテナのタッチイベントが調整されると言っていましたが、私は測って、そうではありません.子ViewのonTouchEventをfasleに返しました.この時、子viewのdispatchTouchEventのデフォルトの戻り値もfalseで、この時イベントは確かに親コンテナに伝わって呼び出しました.ただし、この時点でサブViewのdiapatchTouchEventメソッドを強制的にtrueに戻すと(デフォルトではsuper.dispatchTouchEventを返すのではなく、super.dispatchTouchEventを呼び出してtrueを返す)、onTouchEventがfalseを返したとしても、親コントロールのタッチとクリックイベントは調整されません.
したがって、onTouchEventがfalseの親コンテナに戻るタッチイベントが不正確に落ちるような気がします.dispatchTouchEventがfalseに戻るべきで、親コンテナのタッチイベントが落ちます.onTouchEventがtrue or falseを返しても、dispatchTouchEventがfalseを返していれば、親コンテナのタッチイベントが呼び出されます.
私のテストdemoアドレスはgithubに置いて、必要なものがあればダウンロードして試して、とても例が粗くて、テストに使うだけです.アドレス:https://github.com/happycodinggirl/TestTouchEvent本文の文章に間違いがあれば,指摘してほしい.