2011-12-09 75 views
13

我有一個圖像我顯示給我的android應用程序中的用戶。獲取觸摸座標相對於視圖(ScreenToClient等效?)

我想知道他們'接觸'圖像的位置。

我可以很容易地得到屏幕座標通過實施OnTouchListener

private OnTouchListener image_Listener = new OnTouchListener(){ 
    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     if(event.getAction() == MotionEvent.ACTION_UP) { 
      float x = event.getX(); 
      float y = event.getY(); 
      return true; 
     } 
     return false; 
    } 
}; 

然而,這些絕對座標。我真的需要的是一個功能,將其轉換成相對於視圖的座標..

我已經做了一些挖掘,但我似乎無法調出任何東西,除了我試圖實現ScreenToClient方法我自己..

有沒有人知道這個很好的解決方案,或者我只是將不得不推出自己的?

這似乎是一種可用的方法 - 這就是爲什麼我問。

謝謝大家的時間。

編輯:我不太確定座標是不是已經相對於視圖。我可以發誓讀取的座標是絕對的,但經過一些修補 - 我有事情工作,因爲我的預期..對不起,噪音傢伙。

回答

20

只是回答,觸摸是相對於某種方式來看。是的,它們是觸摸的原始屏幕座標。但是,由於您將觸摸事件註冊到視圖本身,因此只有在用戶實際觸摸視圖時纔會觸發。這意味着,即使屏幕座標是原始屏幕座標,它們也在視圖本身的範圍內。

如果你想獲得觸摸視圖的x/y座標相對於只有自己,那麼你就可以subract與屏幕的左側座標協調,從Y頂部座標的座標,像這樣:

private OnTouchListener image_Listener = new OnTouchListener(){ 
    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     if(event.getAction() == MotionEvent.ACTION_UP) { 
      float screenX = event.getX(); 
      float screenY = event.getY(); 
      float viewX = screenX - v.getLeft(); 
      float viewY = screenY - v.getTop(); 
      return true; 
     } 
     return false; 
    } 
}; 

這樣,如果用戶在屏幕上觸摸了40個x像素,但左邊距設置爲10,那麼viewX將爲30.如果您將視圖向下移動40 x像素,並且用戶觸摸了相同的點在視圖中,它仍然是30.

如果在視圖中包含填充作爲填充,它會變得稍微複雜一些即使它不顯示任何東西,仍然視爲視圖。

編輯:

我應該指出,皮埃爾說的是真實的。如果觸摸視圖,即使將手指拖到視圖邊界之外,它仍會繼續接收觸摸事件,直到手指擡起。這意味着,ACTION_UP可以接收不在邊界內的視圖的觸摸座標。

+0

感謝您的回答。 – syllogism

+0

我到了同樣的問題。從教程中,這些方法,比如view.getLeft()。 「返回視圖相對於其父項的位置。」通常,對於複雜的佈局,調查視圖不是屏幕視圖的直接子視圖。所以Deev提到的方法不能總是適用。任何新想法? – user1914692

+4

嗯,我找到一種方法:使用View.getLocationOnScreen()和/或getLocationInWindow()。 – user1914692

2

觸摸事件座標相對於接收事件的視圖。然而,它們並不侷限於視圖的大小,因爲用戶顯然可以在同一個動作中滑到視圖之外。

在觸發ACTION_UP或ACTION_CANCEL之前,即使指針位於視圖之外,視圖仍將繼續接收動作事件。

您確定監聽器已註冊到正確的視圖嗎?

+0

是的,我註冊了正確的觀點。我得到的東西的工作如我所料。我只是讓事情比他們需要的更困難。感謝您的答覆。 – syllogism

18

我剛剛遇到了同樣的問題,並嘗試使用DeeV解決方案,我總是從getLeft()和getTop()方法得到0。由於改變佈局不是一種選擇(因爲我認爲getTop/Left只與視圖的父級有關),我必須弄清楚如何獲得視圖的絕對位置。

下面是使用getLocationOnScreen(位置)類似的方法:

protected Point getRelativePosition(View v, MotionEvent event) { 
    int[] location = new int[2]; 
    v.getLocationOnScreen(location); 
    float screenX = event.getRawX(); 
    float screenY = event.getRawY(); 
    float viewX = screenX - location[0]; 
    float viewY = screenY - location[1]; 
    return new Point((int) viewX, (int) viewY); 
} 
+0

這一個工作,而'screenY - v.getTop()'不(至少對我來說) – 18446744073709551615

+0

v.getTop()也沒有爲我工作。任何人有任何想法爲什麼? – eliasbagley

+0

@eliasbagley:v.getTop()是相對於v的父項,而screenY是相對於屏幕。它只適用於父母進入屏幕頂部的情況。 – user362178

相關問題