2011-03-12 74 views
15

我創建一個小部件/控制,我可以重複使用,其我創建通過延伸RelativeLayout。然後,在我的一個活動中,我在一個循環中創建了一堆這些小部件。不過,當我想讓每個小部件對點擊作出響應時,我遇到了一個問題。OnTouch的作品,但OnClickListener不?

我發現,設置OnTouchListener作品:

this.setOnTouchListener(new OnTouchListener(){ 
     public boolean onTouch(View arg0, MotionEvent arg1) { 
      //Triggers debug message 
     }  
    }); 

OnClickListener不會:

this.setOnClickListener(new View.OnClickListener(){ 
     public void onClick(View v) { 
      //Doesn't trigger debug message 
     } 

    }); 

這是爲什麼?

+0

你加入這兩個相同的對象? – 2011-03-12 15:23:36

+0

@ nicholas.hauschild - 不,一次一個 - 評論其他人。 – tpow 2011-03-12 15:47:38

+0

您必須在onTouchListener中返回True以防止事件消耗。 – 2014-07-24 06:04:58

回答

15

這裏有一些事情要檢查,以確保您的看法是可以點擊:

View.setClickable() 
View.setEnabled() 
View.setFocusable() 
View.setFocusableInTouchMode() 

取決於你希望得到確切的行爲,你就需要設置其中的一個或多個上。由於您正在獲取onTouch事件,我的猜測是您需要setClickable。但我必須看到視圖創建代碼是肯定的。

+2

感謝您的答覆。我嘗試將所有這些設置爲true,但它不起作用。 – tpow 2011-03-13 20:46:23

+0

將我的擴展相對佈局設置爲「this.setClickable(true);」實際上是答案。我使用「Toast」消息作爲調試語句而不是logcat。原來我使用的是錯誤的上下文對象。感謝兄弟... – tpow 2011-03-17 00:55:55

46

你應該確保該TouchListener不是「消費」觸摸事件。如果從onTouch()方法返回true,Android將考慮它消耗掉,而不是將其傳遞到其他各種觸摸處理程序(這我假設將包括ClickListener)。

你應該這樣做:

this.setOnTouchListener(new OnTouchListener(){ 
    public boolean onTouch(View arg0, MotionEvent arg1) { 
     //Triggers debug message 
     return false; 
    }  
}); 
14

你返回正確的布爾onTouch價值?

從文檔:

onTouch() - 這會返回一個布爾值,表明 監聽是否需用此 事件。重要的是, 這個事件可以有多個動作 隨後對方。因此,如果您在收到關閉事件 事件時返回false,則表明您沒有消耗該事件,並且 也對此事件後續的 操作不感興趣。因此,你 將不會被要求對事件中的任何其他 行動,如 手指手勢,或最終達到 動作事件。

編輯

發現在這個question的解決方案,只是嘗試了一下自己。

你需要在你的onTouchEvent代碼中使用這個return super.onTouchEvent(event);。添加後,OnClickListener開始工作。

+0

有趣和有益的知道...但是,當我測試onClick,我評論出OnTouch – tpow 2011-03-12 15:46:37

+0

@cinqoTimo:編輯答案。試試看看它是否有效。 – Abhinav 2011-03-13 18:08:08

+1

感謝您的更新。但是,我不確定你的意思。觸摸事件會在哪裏發生?我嘗試在我的OnTouchListener中替換「return true」 - 「event」是「MotionEvent」,超類無法識別它。 – tpow 2011-03-13 20:43:33

0

如果由於某種原因而重寫onMotionEvent()方法,並且在這種情況下需要返回true/false,則可以通過在重寫的onMotionEvent()內調用this.performClick()來手動觸發OnClickListener在返回true/false之前。

4

要在onTouch()這樣執行這個返回FALSE:

this.setOnTouchListener(new OnTouchListener(){  
     public boolean onTouch(View arg0, MotionEvent arg1) { 
      return false; 
     }  
}); 
+0

但是這會禁用你的ontouch監聽器......這和將它從應用中刪除一樣。 – Simon 2015-12-17 12:37:03

2

您可以通過onTouchListener實現一個onClickListener:

webView.setOnTouchListener(new View.OnTouchListener() { 

     public final static int FINGER_RELEASED = 0; 
     public final static int FINGER_TOUCHED = 1; 
     public final static int FINGER_DRAGGING = 2; 
     public final static int FINGER_UNDEFINED = 3; 

     private int fingerState = FINGER_RELEASED; 


     @Override 
     public boolean onTouch(View view, MotionEvent motionEvent) { 

      switch (motionEvent.getAction()) { 

       case MotionEvent.ACTION_DOWN: 
        if (fingerState == FINGER_RELEASED) fingerState = FINGER_TOUCHED; 
        else fingerState = FINGER_UNDEFINED; 
        break; 

       case MotionEvent.ACTION_UP: 
        if(fingerState != FINGER_DRAGGING) { 
         fingerState = FINGER_RELEASED; 

         // Your onClick codes 

        } 
        else if (fingerState == FINGER_DRAGGING) fingerState = FINGER_RELEASED; 
        else fingerState = FINGER_UNDEFINED; 
        break; 

       case MotionEvent.ACTION_MOVE: 
        if (fingerState == FINGER_TOUCHED || fingerState == FINGER_DRAGGING) fingerState = FINGER_DRAGGING; 
        else fingerState = FINGER_UNDEFINED; 
        break; 

       default: 
        fingerState = FINGER_UNDEFINED; 

      } 

      return false; 
     } 
    }); 
相關問題