手機螢幕座標

2021-06-21 20:53:30 字數 4667 閱讀 6004

整個座標系是以手機螢幕左上角為原點(0,0),如果在螢幕沒有滑動之前,這一理解肯定是ok的,但在滑屏之後,就會產生很多歧義和混淆,原因在於使用過程當中,很多方法的引數並非是參照螢幕,而是相對于父檢視,對這整個過程和後面自定義控制項的座標變化帶來的各個引數變化來說理解起來就並不那麼適合了,最開始給人的感覺是越來越不清楚這個座標該怎麼設定,好像座標系總在發生變化,後來才慢慢在思維當中構建起檢視與檢視容器以及螢幕之間的關係。

android.view.view.layout(int l, int t, int r, int b)    

layout的過程就是確定view在螢幕上顯示的具體位置,在**中就是設定其成員變數mleft,mtop,mright,mbottom的值,這幾個值構成的矩形區域就是該view顯示的位置,

不過這裡的具體位置都是相對與父檢視的位置

。mleft代表當前view.layout的這個view的左邊緣離它的父檢視左邊緣的距離,拿上面「子檢視2.layout

(int l, int t, int r, int b) 

」來說,它的父檢視便是子檢視1,2,3合起來形成的整個大矩形,那麼這裡將父檢視的左上角定為(0,0),那麼可以確定mleft為乙個子檢視寬度320,以此類推,

mtop指當前view的上邊緣離父檢視上邊緣的距離。而以此為界,

mright所指的是

當前view的右邊緣離父檢視左邊緣的距離

,一眼可以看出值為640(mleft+自己的寬度),mbottom也是指當前view的下邊緣離父檢視的上邊緣的距離。至於為何如此,大概是因為座標系的緣故,座標中的任何點都必須以(0,0)為起點,xy軸為衡量。

檢視左側位置  view.getleft() 

檢視右側位置 view.getright()

檢視頂部位置 view.gettop();

檢視底部位置 view.getbottom();

這四個方法所獲取到的各個左上右下的值與layout的四個引數代表的是一樣的,都是相對父檢視的左邊緣與上邊緣。

檢視寬度 view.getwidth();

檢視高度 view.getheight()

;這兩個方法獲取的是該view的高和寬,僅僅在滑動的情況下,或者說該view的大小如果不發生變化,它的值是不會變的。

getmeasuredwidth();

getmeasuredheight();

說到這裡就不得不提getwidth()、getheight()和getmeasuredwidth()、getmeasuredheight()這兩對函式之間的區別,getmeasuredwidth()、getmeasuredheight()返回的是measure過程得到的mmeasuredwidth和mmeasuredheight的值,而getwidth()和getheight()返回的是mright - mleft和mbottom - mtop的值。

一般情況下layout過程會參考measure過程中計算得到的

mmeasuredwidth和mmeasuredheight來安排子檢視在父檢視中顯示的位置,

但這不是必須的,measure過程得到的結果可能完全沒有實際用處,特別是對於一些自定義的viewgroup,其子檢視的個數、位置和大小都是固定的,這時候我們可以忽略整個measure過程,只在layout函式中傳入的4個引數來安排每個子檢視的具體位置。

view.getx

();view.gety();

getx和gety獲取到的值為相對於

父檢視而言的兩個左邊緣和上邊緣的距離。

view.getlocationonscreen(location);  該方法可以獲取到當前view與

螢幕的關係,location(0)代表x值,表示該view的左邊緣與螢幕的左邊緣之間的距離。可以想象,當滑屏產生,view開始移動該值肯定會改變的。

location(1)代表y值,表示該view的上邊緣與螢幕的上邊緣之間的距離,該距離肯定是包含標題欄的高度的。

getlocationinwindow();  

ps:view.getlocationinwindow()和 view.getlocationonscreen()在window佔據全部screen時,返回值相同,不同的典型情況是在dialog中時。當dialog出現在螢幕中間時,view.getlocationonscreen()取得的值要比view.getlocationinwindow()取得的值要大。

velocitytracker.getxvelocity() 指滑動速度包括速率和方向兩個方面,往左滑動小於0,值為負;往右滑動大於0,值為正。

view.scrollto

(x,y)

將整個父檢視的左上角定為(0,0),再移動這個

螢幕的左上角到父檢視的點(x,y)處,注意此處的x和y是根據父檢視的座標系來定的。

view.scrollby(x,y)  x代表橫向移動的距離,y代表縱向移動的距離

view.getscrollx

view.getscrolly

將整個父檢視的左上角定為(0,0),那麼子view.

getscrollx會獲取到螢幕左邊緣減去父檢視的左邊緣為0的距離,特別當滑屏時,父檢視會被迫隱藏一部分,因為螢幕的大小是固定的。

getscrolly以此類推。

event.getx()

event.gety()

該方法是不受檢視影響的,x和y的值僅僅代表手指在以左上角(0,0)為原點的螢幕觸控點的座標值。

scroller.getcurry()

scroller.getcurrx()

該方法拿橫軸來說,代表螢幕的左邊緣離父檢視的左邊緣的距離。

scroller.startscroll(

int startx, int starty, int dx, int dy

) 四個引數分別表示起點的座標和滑動的向量,即從(

startx,

starty

)開始滑動,橫向滑動dx的距離,縱向滑動dy的距離(

正值向左滑,負值向右滑

),而這裡的

startx,

starty又是參照的父檢視左上角為原點座標的座標系,滑屏時經常使用getscrollx()和

getscrolly()來代表螢幕左邊緣和上邊緣處於父檢視座標系的具體位置

translateanimation()

引數參照:

以上是在做滑屏控制項經常用到的方法,一方面需要了解layout和measure的基本流程,更重要一方面,當你想要實現某乙個效果的時候,比如slidingmenu那樣的控制項,檢視原始碼我們可以知道它是繼承的viewgroup,該怎樣入手去做呢。

首先,需要了解它的父檢視是什麼,slidingmenu為例,開啟程式,第一眼,是乙個很普通的檢視頁面,當向右滑動手指,這個檢視頁面開始向右邊移動,而從左邊會慢慢移出來另一部分檢視,看上去像是抽出來的或者是隱藏的,事實上拋開陰影效果來講,想象手機螢幕的左邊有一部分我們看不到的檢視,它就是這個被抽出來的menu檢視了。概括來說,乙個主view,乙個menu其實是併排於乙個大檢視上面的。

找到了父檢視,接下來就好辦了,認定這個父檢視的寬度就是主view的寬度和menu的寬度之和(暫不考慮padding之類),高度就是螢幕的高度,那麼在思維當中這個二維平面就產生了,將它想成一張紙,然後對準主view將這張紙貼到手機螢幕上,左右滑動,會看到其實slidingmenu也就是這麼個效果。

然後,實現的思路會清晰很多。定義這個父檢視為myview繼承viewgroup,原因在於儘管主view和menu併排在乙個大view下,但畢竟兩者的內容不同,後面需要放進不同的控制項處理不同的事件,這個父檢視內包含著兩個view,到時候處理起來會方便很多,setcontentview為這個父檢視,那麼開啟程式的第一眼就會看到它。再定義這兩個view設定好兩個內容布局,並將它們addview新增到myview當中。外部工作基本就完成了,可以呈現父檢視,並且父檢視內有兩個子view。

接下來,需要去完善一些細節,父檢視內的子view該如何放置,這是關乎成敗的一環,也就是如何將這張紙貼到我們希望的位置,這時就是onlayout的處理了,處理好螢幕,父檢視子view之間的位置關係,通過各自的layout引數設定來擺放妥當各個view,比如開始的時候menu是隱藏的,這個就是通過位置的擺放設定的,然後它是從左邊滑出來的,說明它處於父檢視的左邊位置,而主view處於相對右邊的位置,而螢幕剛好也處於父檢視右邊的位置,恰好能看到主view的全貌,在腦海裡如果能有清晰的畫面出現,實現起來就會輕鬆很多。當實現了這個擺放,就可以理解menudrawer裡面上下左右都可以滑出menu的結構了。

最後,便是滑動效果,請相信這樣的控制項裡面,任何處理肯定都會和view位置的擺放扯上關係,滑動方向,滑動距離等等都涉及到座標的處理。這也是為何上面列出那些常用的獲取view座標的方法。

總結下來,構建類似這樣的控制項,也就這三點,明確父子檢視和螢幕的關係,通過座標和位置引數設定它們的關係,處理這些關係發生變化的情況。

當然,事實上slidingmenu遠遠沒這麼簡單,其中為了方便後續開發,它內建了很多介面和處理,大多數都是位置座標和事件監聽相關聯,而萬變不離其宗的是,它也肯定有這三個方面的構建,理解了這些基本的東西,嘗試做一些自己想象的效果,對自定義的理解來說,進步會非常大。

Unity Shader 螢幕抓取,螢幕座標

抓取螢幕,抓取後名字為name 獲取螢幕座標有3種方法 sv position語義的xy 使用sv position語義,在片元著色器中拿到的pos.xy就是螢幕空間的座標。struct v2f vpos語義 vpos語義和sv position衝突,使用vpos語義,則v2f不能定義sv posi...

opengl 螢幕座標

建立opengl模型過程 opengl座標變換很有特點,為了簡單描述先定義2個座標系 1 世界座標系 無論如何變換,世界座標系都不動,以螢幕中心為原點 0,0,0 你面對螢幕,你的右邊是x正軸,上面是y正軸,螢幕指向你的為z正軸。2 當前繪圖座標系 即區域性座標系 當前繪圖座標系是繪製物體時的座標系...

螢幕座標系

三點定義乙個三角形。當我們在三維圖形學中談論 點 point 時,我們經常說 頂點 vertex 乙個頂點有三個座標 x,y和z。你可以用以下方式來想象這三個座標 x 在你的右方 y 在你的上方 z 是你背後的方向 是的,背後,而不是你的前方 這裡有乙個更形象的方法 使用右手定則 x 是你的拇指 y...