2010-11-11 60 views
16

我想在一個簡單的Android應用程序上檢測到拋出事件,但第一個MotionEvent參數始終爲空。爲什麼用空參數調用onFling方法? Android documentation表示在發生突發事件時使用向下MotionEvent上的初始和匹配的MotionEvent調用它。Android SimpleOnGestureListener.onFling得到一個null MotionEvent

class MyGestureDetector extends SimpleOnGestureListener { 
    @Override 
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
     // e1 always == null, return early a null reference exception 
     if (e1 == null) { 
      return false; 
     } 
     if (e1.getY() - e2.getY() > 120) { 
      handleFlingEvent(); 
      return true; 
     } 
     return false; 
    } 
} 

主要活動有這樣的onTouchEvent方法:

GestureDetector flingDetector = new GestureDetector(new MyGestureDetector()); 

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    if (flingDetector.onTouchEvent(event)) { 
     return true; 
    } 
    return super.onTouchEvent(event); 
} 

回答

2

我有類似的問題。它發生在GestureDetector和onFling方法在自定義視圖類中,這是活動UI的一部分。經過一系列測試後,我發現只有主要活動可以很好地檢測到滑動手勢。所以我通過在活動中替換它們來解決問題。但是我沒有找到這個問題的根源。

+0

我得到它的工作,但我永遠無法確定它最終做了什麼。你的解決方案適用於我的情況,所以我接受了你的答案。我仍然想知道爲什麼它不起作用。 – mcrumley 2011-01-05 07:14:08

+0

我也是。我想知道爲什麼它不起作用。希望有人回答。 – 2011-01-08 09:01:18

+0

你有幸跟蹤造成這種情況的原因嗎?我患有同樣的問題,但即使在主要活動中使用onFling方法,也似乎無法使其工作。 – 2011-01-30 11:39:48

2

我在水平線性佈局中有3個按鈕,而這個佈局又被horizontalscrollview包圍。

然後我在horizontalscrollview上設置了simplegesturelistener,並得到與上面相同的錯誤。然後我也爲佈局中的所有按鈕設置simplegesturelistener,並且它工作正常。

12

我第一次遇到Android 4.0的這個問題,因爲我的代碼在所有以前的版本中工作正常。從這裏的建議中得到一個提示後,我發現一個簡單的解決方法就是跟蹤onDown事件,並使用它來代替onFling的第一個參數,以防它碰巧爲null。

public class MySimpleGestureListener extends SimpleOnGestureListener { 
    protected MotionEvent mLastOnDownEvent = null; 

    @Override 
    public boolean onDown(MotionEvent e) { 
     mLastOnDownEvent = e; 
     return true;//super.onDown(e); 
    } 

    @Override 
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
     if (e1==null) 
      e1 = mLastOnDownEvent; 
     if (e1==null || e2==null) 
      return false; 
     float dX = e2.getX()-e1.getX(); 
     float dY = e2.getY()-e1.getY(); 
     ...rest of code 
    } 

    ...rest of class 
} 
+0

我試過這個,但它沒有解決我的問題。 onDown不被調用,e1仍然爲空。 – fobbymaster 2016-03-17 21:18:56

+0

@ onDown'回調中的@fobbymaster只返回'true'而不是'super.onDown(e)' – 0neel 2016-12-05 14:59:03

0

來源我認爲onDown事件已被滾動型恢復,所以我們不能獲得活動中的事件。如果您自定義ScrollView並重寫dispatchTouchEvent()和onTouchEvent(),則問題將解決。

活動:

public class TestActivity extends Activity { 
    private MyScrollView scrollView; 
    private TestActivity me; 
    private GestureDetector detector; 

    protected void onCreate(Bundle savedInstanceState) { 
      this.me = this; 
      MySimpleGestureListener gestureListener = new MySimpleGestureListener(); 
      this.detector = new GestureDetector(gestureListener); 
      this.scrollView.setOnTouchListener(onTouchListerner); 
      this.scrollView.setDetector(detector); 
    } 

    private View.OnTouchListener onTouchListener = new View.OnTouchListener() { 
    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     return me.detector.onTouchEvent(event); 
    } 
}; 
} 

MySimpleGestureListener:

public class MySimpleGestureListener extends SimpleOnGestureListener { 
    @Override 
    public boolean onSingleTapUp(MotionEvent e) { 
     return false; 
    } 

    @Override 
    public void onShowPress(MotionEvent e) { 

    } 

    @Override 
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, 
      float distanceY) { 
     return super.onScroll(e1, e2, distanceX, distanceY); 
    } 

    @Override 
    public void onLongPress(MotionEvent e) { 
    } 


    @Override 
    public boolean onDown(MotionEvent e) { 
     return false; 
    } 

    @Override 
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, 
      float velocityY) { 
        // TODO do your onFling here 

    } 
} 

最後,MyScrollView

public class MyScrollView extends ScrollView { 
    private GestureDetector detector; 

    @Override 
public boolean dispatchTouchEvent(MotionEvent ev){ 
    if (this.detector!= null) { 
      detector.onTouchEvent(ev); 
     super.dispatchTouchEvent(ev); 
     return true; 
    } 
    return super.dispatchTouchEvent(ev); 
} 

@Override 
public boolean onTouchEvent(MotionEvent ev) { 
    super.onTouchEvent(ev); 
    // 
    if (this.detector != null) { 
     return this.detector.onTouchEvent(ev); 
    } 
    return false; 
} 

    // here is the getter and setter 
} 

希望這有助於。

3

在自定義視圖組類中,您需要覆蓋2個方法:onInterceptTouchEventonTouchEvent。之後,您需要在兩種方法中調用GestureDetector.onTouchEvent()。事件ACTION_DOWN僅傳遞給onInterceptTouchEvent

@Override 
public boolean onInterceptTouchEvent(MotionEvent event) { 
    if(mDetector.onTouchEvent(event)) { 
     return true; 
    } 
    return super.onInterceptTouchEvent(event); 
} 

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    if(mDetector.onTouchEvent(event)) { 
     return true; 
    } 
    return super.onTouchEvent(event); 
}