2010-12-15 14 views
2

2つのビューを持つ単純なアプリケーションがあります.1つはTableViewで、もう1つはListViewです。私はGestureDetectorを使用して、画面全体のスワイプをどのようにして検出するかをhereとします。リストビューに少数のアイテムが入力されていれば、ListViewが画面全体をいっぱいにしてもジェスチャーの検出は機能しなくなりますが、すべて正常に機能します。画面全体をスワイプすると、リスト項目の1つが強調表示されます。ジェスチャー検出器がスクロール可能なリストアクティビティで機能しない

ListViewが何らかの形でGestureListenerからタッチイベントを盗むので、これが起こっていると思います。これを防ぐ方法はありますか?

答えて

1

カスタムリストビューを作成し、ジェスチャ検出器をリストの各行に実装することができます。試してみる価値があるかもしれません。

+0

私はそれについて考え、何かクリーナーを探しています。 – Vlad

2

かなり正確な水平パスをトラバースすると、ListItemsでGestureDetectorが正常に動作することがわかりました。しかし、少し浮いた場合、リストがスクロールしてジェスチャーが完了しません。次のように何が起こっていることである。

  • GestureDetectorは喜んであなたがsetOnTouchListener()を介してのListItemにインストールonTouchからMotionEventsを取ってオフに開始されます。
  • ListViewはonInterceptTouchEvent()経由で子ビューに送信されたイベントをリッスンします
  • リストビューは、スクロールを開始したことを検出し、onInterceptTouchEvent()からtrueを返します。
  • その後、MotionEventsはListViewに送信され、元のターゲットには送信されません。リストビューはonTouchハンドラでMotionEventsの受信を開始します。これは最後のACTION_UPまで続きます。 (ACTION_DOWNからACTION_UPまでのMotionEventsは1つのジェスチャーとみなされ、シーケンス内の最後のACTION_UPの後にすべてが再び開始されます)
  • 元のターゲット(ListItem)は、ListItem bailsのACTION_CANCEL MotionEventとGestureDetectorを取得しますでる。これは、GestureDetector用のコードをアプリに貼り付けて実行すると発生します。

私のアプリは、タッチが水平からわずかにずれても水平スワイプが続くように動作する必要がありました。

解決策: これには、親がモーションイベントを覗くことを停止するViewGroup.requestDisallowInterceptTouchEvent(boolean disallowIntercept)が含まれます。この方法では、onTouchListenerを実装してわずかなスワイプ(10ピクセル程度)を検出し、親のインターセプト動作イベントを停止します。親はスクロールせず、ジェスチャー検出器は完了し続ける。

は、ここでは、コードです:

private boolean mFlingInProgress = false; 
private float mStartX = 0; 
private final int FLING_TRIGGER_DISTANCE = 10; 

@Override 
public boolean onTouch(View v, MotionEvent event) { 
    int action = event.getAction(); 
    float currentX = event.getRawX(); 

    switch (action) { 
    case MotionEvent.ACTION_DOWN: 
     mStartX = currentX; 
     break; 
    case MotionEvent.ACTION_MOVE: 
     if (false == mFlingInProgress) { 
      if (Math.abs(currentX - mStartX) > FLING_TRIGGER_DISTANCE) { 
       // stop the parent intercepting motion events 
       mLayout.getParent().requestDisallowInterceptTouchEvent(true); 
       mFlingInProgress = true; 
      } 
     } 
     break; 
    case MotionEvent.ACTION_UP: 
     mFlingInProgress = false; 
     break; 
    } 

    return mGestureDetector.onTouchEvent(event); 
}