Pages

2011年11月15日 星期二

[Cupcake] Multi-touch Part2

以下是在 Androdi 1.5 Platform 實現,當初的 MotionEvent 並沒有 Multi-Touch 相關欄位,所以是拿 size(4 bytes) 欄 來替代,現在 2.x 版已經有這些欄位。

  1. 在實作拖拉、放大縮小、旋轉、輕滑,我們訂定五種狀態:NOTHINGDRAG(一指)STRETCH(兩指)FLICK(兩指)ROTATE(兩指),如同 Finite State Machine。
  2. 如果一次同時點下兩個點,根據我們 flag 的設定,會顯示兩個點都 true,但 Application 需要收兩次,所以三個 state 一個也不能少:
    //
    雖然都是 true,此時只有第一個點座標,所以只能先把狀態弄成 DRAG

    (mPoint1.down, mPoint2.down, (x1, y1, pressure1)) = (true, true, (xxx.xxx, xxx.xxx, xxx.xxx)) 


    //
    第二個點座標收到了,狀態改成 STRETCH

    (mPoint1.down, mPoint2.down, (x2, y2, pressure2)) = (true, true, (xxx.xxx, xxx.xxx, xxx.xxx))
  3. 在 Gallery 的部分,採用 dispatchTouchEvent;在放大縮小的部分,採用 ZoomButtonController,可藉由實作他的 Listener,來處理 MotionEvent。所以,如果去點那兩個按鈕,此時的super.dispatchTouchEvent 會回傳 true,而且 Listener 可以接受到事件並且處理。
  4. 如果覆寫 OnTouchEvent,且該函式回傳 true,那麼按鈕就接收不到事件;如果回傳 false,那麼第二根手指下去就接收不到。所以目前放棄覆寫他, 實作 Multi-touch 的部分放在 dispathTouchEvent。
  5. 判斷軌跡是每一次事件觸發就去做回應,並非判斷完一整串軌跡才做。以兩點為例,目前想到的判斷方式如下:
    • 兩點間的x距離、y距離、或距離。
    • 點的移動速度。(這裡可以考慮單位時間,也就是說,移動距離大的代表速度很快)
    • 壓下去的時間長短,MotionEvent有getDownTime和getEventTime。(如:long press)
    • 兩點連線與水平的夾角
    • 底層傳上來的壓力值。(目前使用義隆電的板子,壓力值都是回傳 0.5xxx,所以無法使用)
    • Touchpad 被點下去的位置。
    • 斜率。(不確定適不適合)
  6. 因為 onTouchEvent 和 dispatchTouchEvent 處理事件的頻率和底層不同,所以要處理歷史訊息。
    • getHistorySize()
    • getHistoricalX(i)
    • getHistoricalY(i)
    • getHistoricalPressure(i)
    • getHistoricalSize(i)
    然後再處理當下的事件      
    • getX()
    • getY()
    • getPressure()
    • getSize()

沒有留言:

 
Blogger Templates