onIntercept TouchEvent()とonTouch Event()の仕組み


From:http://www.dewen.org/q/2438/android%E8%A7%A6%E5%B1%8F%E4%BA%8B%E4%BB%B6%E5%A4%84%E7%90%86onInterceptTouchEvent%E7%9A%84%E9%97%AE%E9%A2%98
Androidの公式文書には標準的な説明があります。ここから抜粋します。まず、Androidの公式文書を見て正解します。

   
   
   
   
  1. onInterceptTouchEvent() onTouchEvent() :
  2.   1. down onInterceptTouchEvent()
  3.   2. ViewGroup onInterceptTouchEvent() down return falsemove, up ViewGroupdown view onTouchEvent()
  4.   3. ViewGroup onInterceptTouchEvent() down return truemove, up onInterceptTouchEvent(), down ViewGroup onTouchEvent() , , view
  5.   4. view onTouchEvent() falseview onTouchEvent()
  6.   5. view onTouchEvent() trueview onTouchEvent() 。
この公式文書の説明を見るだけで、この二つの関数関係と用途は経験豊富なframe ebookの達人であることが分かります。そうでなければ、判例が必要です。このようなlayoutがあると仮定して、非常に典型的です。

   
   
   
   
  1. <com.test.LayoutView1 xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:orientation="vertical" android:layout_width="fill_parent"  
  3.     android:layout_height="fill_parent">  
  4.     <com.test.LayoutView2  
  5.         android:orientation="vertical" android:layout_width="fill_parent"  
  6.         android:layout_height="fill_parent" android:gravity="center">  
  7.         <com.test.MyTextView  
  8.             android:layout_width="wrap_content"   android:layout_height="wrap_content"  
  9.       />  
  10.     </com.test.LayoutView2>  
  11. </com.test.LayoutView1>
このlayoutを例図で説明する:
通常の外周のlayoutview 1、layoutview 2は、レイアウトの容器だけがタッチパネルのクリックイベントに応答する必要はなく、Mytextviewだけが必要です。しかし、これは一般的なケースで、いくつかの特殊なレイアウトは、周辺のコンテナにも応答して、中のmystextviewに応答しないようにします。さらに、応答オブジェクトを動的に交換する場合があります。まず、デフォルトのタッチスクリーンイベントの2つの関数間の伝達の流れを見てください。次の図のように
MyTextViewをタッチスクリーンイベントに応答させたいだけで、MyTextViewのOnTouchEventをtrueに戻すと、イベントフローは次の図になります。layoutview 1が見られます。layoutview 2はもうOnTouchEventに入れられません。
もう一つのケースは、周辺の容器が独自にタッチスクリーンイベントを処理したいということです。対応するオンインテットタッチ・イベント関数の中でtrueに戻り、タッチスクリーンイベントをキャプチャするという意味です。例えば、ラウトビュー1を切り取り処理して、処理フローは次の図になります。
この類推によって、私達は各種の具体的な情況を得ることができて、全体のlayoutのview種類のレベルの中ですべて機会があって切り取って、その上外周の容器のviewが優先的な傍受権を持つことを見抜くことができます。
私たちは相対的に複雑なタッチスクリーンのインタラクティブ効果を持つアプリケーションを行うとき、常に動的にtouch eventの処理対象を変更する必要があります。例えば、launcher待受デスクトップとメインメニュー(下図参照)、スライドスクリーンからスライド停止までの過程の中で、周辺のコンテナviewだけがtouch eventを処理できます。上のアプリケーションアイコンやwidgetを誤ってクリックします。逆に静止して動かない状態では、アイコンのtouchイベントに応答する必要があります。fram eworkのabslitviewコードを摘出しました。次の通りです。

   
   
   
   
  1. public boolean onInterceptTouchEvent(MotionEvent ev) {
  2.         int action = ev.getAction();
  3.         switch (action & MotionEvent.ACTION_MASK) {
  4.         case MotionEvent.ACTION_DOWN: {
  5.  
  6.             if (touchMode == TOUCH_MODE_FLING) {
  7.                 return true;  //fling , touch, , view
  8.             }
  9.             break;
  10.         }
  11.         case MotionEvent.ACTION_MOVE: {
  12.             switch (mTouchMode) {
  13.             case TOUCH_MODE_DOWN:
  14.                 final int pointerIndex = ev.findPointerIndex(mActivePointerId);
  15.                 final int y = (int) ev.getY(pointerIndex);
  16.                 if (startScrollIfNeeded(y - mMotionY)) {
  17.                     return true;// , touch , view
  18.                 }
  19.                 break;
  20.             }
  21.             break;
  22.         }
  23. }
まとめ:
概観的な公式文書だけでは、onIntercept TouchEvent関数の用途は分かりにくいです。この抽象的なルールを演繹することによって、図面を添えてこそ、この重要な知識を得ることができます。明らかに、デフォルトはfalseに戻ります。trueに戻った後、イベントフローのバックエンドコントロールはtouchイベントを処理する機会がなくなりました。デフォルトのイベントフローの各処理関数をノードとして見ました。このノードはtrueに戻るだけで、後続のイベントは終了します。