2013-07-24 48 views
2

我正在開發自定義ViewGroup。它是某種圓形菜單(類似於android相機應用程序中的選項菜單)。自定義ViewGroup.dispatchTouchEvent()無法正常工作

我設法佈置並正確繪製兒童。我不得不這樣做的另一件事是覆蓋觸摸事件調度:

@Override 
public boolean dispatchTouchEvent(MotionEvent ev) { 
    for (int i=0; i<getChildCount(); i++) { 
     CircularView child=(CircularView) getChildAt(i); 
     if (child.viewMetrics.containsPoint(ev.getX(), ev.getY())) { 
      child.dispatchTouchEvent(ev); 
      return true; 
     } 
    } 
    return false; 
} 

我通過孩子和調度事件循環,如果事件的座標屬於任何人(child.viewMetrics.containsPoint()方法調用,雙重檢查,正常工作)。

似乎工作,但它並不完美。我注意到問題:當我點擊時,握住我的手指並稍微移動它,點擊就會中斷。 Here's the demo

我看着superclass implementation,並有大量的代碼。我的第一個想法是複製它,但它取決於許多私人課程。

我如何確保觸摸事件的正確調度的作品?(不僅點擊,但所有其他手勢以及?) 如果沒有簡單的方法來做到這一點,我將不勝感激任何意見或建議移植默認實現或任何鏈接到有關該主題的有用信息。

回答

9

當調度touchEvents,你應該偏移的位置到視圖左/頂。

導致在scrollx的800x400上點擊(而scrollX = 200)意味着你正在觸摸一個視圖在1000x400,那麼你知道哪個視圖已被觸及,它的界限就像ltrb(950,0 ,1050,600),爲了正確調度它,你應該在你調度的事件中抵消x,y的值,這意味着你發送一個MotionEvent(50,400)到子視圖。

視圖會妥善處理的TouchEvent,並將其分配給兒童或處理本身。

有一個提示是,有時一個視圖,而調度將通過某個值設置事件,並且下一個MotionEvent將不再與循環後的原始值相等,因此您應該將副本發送給子級。

在恢復,它是一種這樣的:

MotionEvent cp = MotionEvent.obtain(event); 
cp.offset(-child.getLeft(), -child.getTop()); 
boolean consumed = child.dispatchTouchEvent(cp); 
cp.recycle(); 
return consumed; 

我不得不重寫幾類dispatchTouchEvent /的onTouchEvent這不正常工作。

另外:我沒有觀看YouTube視頻,可能你的一些意見攔截的觸摸事件,併發送ACTION_CANCEL你的意見,這就是爲什麼你失去的事件。 (這發生在我身上,這就是爲什麼我重寫所有視圖類的調度/ onTouch)

+0

作爲座標,我離開他們的是(爲了方便起見,所有的孩子使用相同的座標相對於圓心繫統)。如果我做短的點擊,事件被正確地發送。此外,子節點('CircularView'及其子節點)僅覆蓋繪圖方法(因此可能不會發送ACTION_CANCEL,但我認爲需要再次檢查)。至於你的其他建議,我會盡快嘗試。 –

+0

似乎座標是這種情況。我檢查了默認行爲,它們在事件分派給孩子之前被修改。謝謝你的幫助! –

相關問題