2015-02-10 97 views
5

我創建了一個自定義組件與onTouchListener和手勢檢測器, 我把自定義組件放在MainActivity的xml文件,它也有onTouchEvent和手勢檢測器。 我想檢測自定義組件上的單擊和長按MainActivity,但它似乎以某種方式觸摸監聽器進行交互,並且單擊不會被檢測到。SimpleOnGestureListener的onSingleTapUp從來沒有叫

MainActivity.java:

public class MainActivity extends ActionBarActivity { 
private GestureDetector detector; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    detector = new GestureDetector(this, new LongPressDetector()); 
} 

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    detector.onTouchEvent(event); 
    int action = event.getActionMasked(); 
    switch (action){ 
     case MotionEvent.ACTION_DOWN:{ 
      Log.d("TouchEvent", "Action_Down at MainActivity.java"); 
      break; 
     } 
    } 
    return super.onTouchEvent(event); 
} 

private class LongPressDetector extends GestureDetector.SimpleOnGestureListener{ 
    @Override 
    public boolean onDown(MotionEvent e) { 
     Log.d("TouchEvent", "onDown at MainActivity.java"); 
     return super.onDown(e); 
    } 

    @Override 
    public void onLongPress(MotionEvent e) { 
     Log.d("TouchEvent", "onLongPress at MainActivity.java"); 
     super.onLongPress(e); 
    } 
} 
} 

CustomView.java:

public class CustomView extends RelativeLayout { 
private GestureDetector detector; 

public CustomView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    init(context); 
} 

private void init(Context c){ 
    LayoutInflater layoutInflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    layoutInflater.inflate(R.layout.customview, this); 
    detector = new GestureDetector(c, new TapDetector()); 
    this.setOnTouchListener(new OnTouchListener() { 
     @Override 
     public boolean onTouch(View v, MotionEvent event) { 
      detector.onTouchEvent(event); 
      int action = event.getActionMasked(); 
      switch (action){ 
       case MotionEvent.ACTION_DOWN:{ 
        Log.d("TouchEvent", "Action_Down at CustomView.java"); 
        break; 
       } 
      } 
      return false; 
     } 
    }); 
} 

private class TapDetector extends GestureDetector.SimpleOnGestureListener{ 
    @Override 
    public boolean onDown(MotionEvent e) { 
     Log.d("TouchEvent", "onDown at CustomView.java"); 
     return super.onDown(e); 
    } 
    @Override 
    public boolean onSingleTapUp(MotionEvent e) { 
     Log.d("TouchEvent", "onSingleTapUp at CustomView.java"); 
     return super.onSingleTapUp(e); 
    } 
} 
} 
+0

添加Log.d在onTouch方法,看看事件 – pskink 2015-02-10 09:23:54

+0

我做,如果我的自定義組件的挖掘,從而觸發的事件是:在CustomView onDown。 java的; CustomView.java的Action_Down; onDown at MainActivity.java; MainActivity.java的Action_Down; 但沒有onSingleTapUp – daxter1992 2015-02-10 09:26:32

+0

現在讀什麼omTouch返回 – pskink 2015-02-10 09:27:47

回答

12

如果你要到一個水龍頭了,你還需要從onDown返回true迴應,默認會返回false (我在這裏猜測)。

至少對我來說,無論如何,我沒有得到onSingleTapUp要求我的代碼,直到我確信onDown返回true。

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

我在哪裏見過「向上」事件僅當「向下」事件接受交付其他的框架,所以我認爲這是發生了什麼事在這裏。

3

有沒有必要猜測(@alexndr)!看看源

如果u擴展GestureDetector.SimpleOnGestureListener調用super.onDown(事件)

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

將返回false,但如果u實現姿態探測器監聽那麼就沒有超強!

public class GestureDetector { 
/** 
* The listener that is used to notify when gestures occur. 
* If you want to listen for all the different gestures then implement 
* this interface. If you only want to listen for a subset it might 
* be easier to extend {@link SimpleOnGestureListener}. 
*/ 
public interface OnGestureListener { 

    /** 
    * Notified when a tap occurs with the down {@link MotionEvent} 
    * that triggered it. This will be triggered immediately for 
    * every down event. All other events should be preceded by this. 
    * 
    * @param e The down motion event. 
    */ 
    boolean onDown(MotionEvent e); 

ps。規則很簡單:

如果事件被消耗返回true 如果沒有返回FALSE

0

你只需要在你的onTouchEvent(MotionEvent event)返回true。

有點像這樣:

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    detector.onTouchEvent(event); 
    int action = event.getActionMasked(); 
    switch (action){ 
     case MotionEvent.ACTION_DOWN:{ 
      Log.d("TouchEvent", "Action_Down at MainActivity.java"); 
      break; 
     } 
    } 
    return true; 
}