Android屏幕適配詳解

剛做Android開發時就研究過屏幕適配的專題,後來只記得常用的那些東西,不常用的就忘了,等再要用的時候又要去查,這次把之前的研究總結一下,記錄下來,方便以後查閱。

ppi、dpi、dp詳解

1、ppi
Pixel per inch,每英寸像素數,表示顯示設備的像素密度。

2、dpi
dot per inch,每英寸多少點,表示印刷品的印刷密度。針對顯示設備時,dpi等同於ppi。

密度計算方法:假設屏幕4.0寸、分辨率800*480,所以該屏幕的dpi = 對角線像素點總數/4,根據勾股定理,即dpi=√(1920^2 + 1080^2)/4

3、dp
安卓開發專用單位,在160dpi屏幕上,1dp=1px,320dpi屏幕上,1dp=2px。

dp值代表的物理長度是固定的,比如:
屏幕3.0寸、分辨率300*400,對角線500px,大概是160dpi,1dp等於1px,物理長度大概是(1/500)*3.0
屏幕3.0寸、分辨率600*800,對角線1000px,大概是320dpi,1dp等於2px,物理長度大概是(2px/1000px)*3.0
屏幕6.0寸、分辨率300*400,對角線500px,大概是80dpi,1dp等於0.5px,物理長度大概是(0.5/500)*6.0

可以看出,無論屏幕大小、分辨率怎麼變,dp對應的px值是隨比例變化,px佔屏幕的比例也是隨比例變化,最終物理長度保持固定。

XXXdpi限定符

mdpi(160dpi)、hdpi(240dpi)、xhdpi(320dpi)、xxhdpi(480dpi)。。。這兩種是一樣的,但是谷歌限定了只能以80dpi爲步進(res資源中出現xxx-180dpi文件夾就會報錯),所以退出了m/h/xh/xxh等符號,來防止開發者使用其它數值。

匹配規則:如果一個屏幕爲280dpi,優先去hdpi找對應的資源,如果沒有hdpi資源文件夾或該文件夾下沒有對應的資源,就去高一級的dpi資源下找,如果沒有就繼續往高一級找。最後還是沒有找到,就去低一級找(即mdpi),最後還沒找到就使用默認values資源,如果默認values資源下也沒有,就報錯。

使用規則:該限定符主要是使用在drawable資源上,因爲dimen可以使用dp單位,在各種dpi下對應的物理尺寸都是一樣的,而圖片的單位是px,所以xxxdpi限定符主要應用與圖片適配上。
對於mdpi的手機,會使用drawable-mdpi資源下的圖片,但是如果沒找到,就會使用其它hdpi資源下的圖片,爲了保證這種情況下的顯示效果,有如下規則:
drawable-mdpi資源下的圖片顯示到mdpi手機上是原圖顯示,顯示到hdpi手機上會把圖片拉伸(240/160)倍後顯示,顯示到xhdpi手機上會拉伸(320/160)倍。。。依次類推;

drawable-xhdpi資源下的圖片顯示到xhdpi手機上是原圖顯示,顯示到mdpi手機上會拉伸(160/320)倍,顯示到hdpi手機上會拉伸(240/320)倍。。。依次類推。

swXXXdp限定符

使用dp值能保證不同屏幕下的物理尺寸是一致的,但是有兩個缺點:1.dpi的步進是固定的,239dpi的屏幕,只能使用160dpi資源下的尺寸,效果很差;2.很多時候我們並不希望物理尺寸一致,而是希望跟隨屏幕大小按比例改變。

使用values-sw300dp限定符,sw:small width的縮寫,即短邊寬度,不關注屏幕方向。該限定符可以指定任意數值的dp,步進爲1dp。

對於手機app來說,大多數情況下,我們想要某個控件的寬度按屏幕寬度比例,這樣可以保證左右兩側的空間都能完全顯示。而高度卻不需要,因爲手機可以上下滑動的。

匹配規則:屏幕寬度dp值必須大於values-swXXXdp中的XXX值,取最接近的。

同一個dimen,在sw300dp下的值爲30dp、sw350dp下的值爲35dp、sw400dp下的值爲40dp。。。。基本可以保證該dimen總是佔屏幕的1/10左右,步進越小越精確。

1920x1080、1280x720限定符

但是某些情況下,需要尺寸完全精確地隨屏幕寬高變化,就需要通過分辨率限定符了。比如values-1920x1080,指分辨率爲1920*1080,1920和1080的順序隨意。同時有values-1920x1080和values-1080x1920資源會資源重複錯誤。

匹配規則:屏幕長邊必須大於values-XXX*XXX中的長邊,屏幕短邊必須大於values-XXX*XXX中的短邊,然後取最接近的。

使用這種限定符,dimen的值就要使用px了,比如你希望某個控件的寬、高均佔屏幕寬、高的1/10,那麼在values-1920x1080資源下width值就爲108px、height值就爲192px,在values-1280x720資源下就分別爲72px、128px了。

這種限定符的優點是足夠精確,缺點是需要維護的文件太多,目前主流的手機至少有十幾種分辨率,每次增加一個dimen值,需要同步到十幾個資源文件下。

對於有虛擬按鍵的手機,需要減去虛擬按鍵的高度,使用實際高度值。比如1920x1080的手機,如果帶虛擬按鍵的話,實際高度是getWindowManager().getDefaultDisplay().getHeight(),而不是1920。

其他限定符

除了上面幾種常用的限定符之外,還有很多沒那麼常用的限定符,而且它們是有優先級的。

所有限定符按優先級排列:mcc310(運營商)-en(語言)-sw320dp(小邊寬度)-w720dp(最佳寬度)-h720dp(最佳高度)
-large(size)-long(長短屏模式)-port(橫豎屏)-car(dock模式)-night(白天或夜晚)-ldpi(最佳dpi)-notouch(觸摸屏模類型)

-keysexposed(鍵盤類型)-nokey(硬按鍵類型)-navexposed(方向鍵是否可用)-nonav(方向鍵類型)-v7(版本)。

優先級使用場景:有values-sw320dp、values-mdpi和values-1920x1080三個資源文件
只要機器滿足sw320dp,就會選擇sw320dp,不會去判斷mdpi和1920c1080;如果不滿足再判斷是否滿足mdpi;最後纔會判斷是否滿足1920x1080。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章