2010-12-15 71 views
2

我有一個簡單的應用程序與兩個視圖,一個是TableView和另一個是ListView。我使用GestureDetector來檢測屏幕上的滑動操作,類似於如何完成here。一切正常,如果列表視圖只填充了幾個項目,但是當ListView填滿整個屏幕時,手勢檢測將停止工作。在屏幕上滑動只需顯示一個列表項。手勢檢測器無法與滾動列表活動

我想這是因爲發生了莫名其妙的ListView搶斷從GestureListener觸摸事件。有沒有辦法來防止這種情況?

回答

1

你可以創建一個自定義列表視圖,然後實現手勢檢測這即內部在列表的每一行。可能值得一試。

+0

我想過這個問題,但尋找的東西乾淨。 – Vlad 2010-12-15 21:49:10

2

我發現,如果你遍歷一個相當準確的水平路徑GestureDetector工作在listItems中的罰款。但是,如果您稍微偏離目標,則列表會滾動並且手勢未完成。發生了什麼如下:

  • GestureDetector開始從通過setOnTouchListener()安裝在ListItems中的onTouch中獲取MotionEvents。
  • ListView同時監聽通過onInterceptTouchEvent()發送給其子視圖的事件。ListView檢測到您已經開始滾動並從onInterceptTouchEvent()返回true。
  • 從那時起,MotionEvents發送給ListView,而不是原來的目標... ListView控件開始接收在其onTouch處理MotionEvents。這一直持續到最後的ACTION_UP。 (請注意,從ACTION_DOWN通過所有ACTION_MOVE到ACTION_UP的MotionEvents被視爲單個手勢,並且在序列中的最後ACTION_UP之後,所有事件都會重新開始)
  • 原始目標(ListItem)在您的ListItem中獲取ACTION_CANCEL MotionEvent和GestureDetector bails出。如果您將GestureDetector的代碼粘貼到您的應用程序並逐步完成,就會發生這種情況。

我需要我的應用程序表現得好像水平滑動繼續,即使觸摸從水平稍微偏離。

SOLUTION: 這涉及ViewGroup.requestDisallowInterceptTouchEvent(布爾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); 
}