所以光看屏幕的分辨率對於設計師來說是不具備多少實際意義的,通過分辨率計算得出的像素密度(PPI)才是設計師要關心的問題,我們通過屏幕分辨率和屏幕尺寸就能計算出屏幕的像素密度的。
再次使用 iPhone(6~7)作為例子。我們知道該屏幕的橫向物理尺寸為 2.3 英寸 ,且橫向具有 750 顆像素,根據下面的公式,我們能夠算出 iPhone(6~7)的屏幕是 326 PPI,意為每寸存在 326 顆像素。
其實不論我們怎么除,計算得出來的像素密度(PPI)都會是這個數,寬存在像素除以寬物理長度,高存在像素除以高物理長度,得數都接近於 326。
對設計會造成什么樣的影響
一塊 326*326px 的正方形色塊在一台 iPhone 7 上面展現出來的物理尺寸將會會是 1*1 英寸。這是因為該屏幕每英寸能容納 326 顆像素,所以 326px 湊在一起剛好就是 1 英寸。假設我們能將 iPhone 7 手機屏幕 PPI 調低 50% 變為 163,色塊還是 326*326px,這個色塊的物理尺寸會變成 2*2 英寸,同樣多的像素,看起來卻大了一倍。咦!這是為啥?
因為我們的色塊是 326*326px 大小的,而這台 163PPI 的假 iPhone 7 每英寸上面只有 163 顆像素,為了要展示 326*326px 的色塊,它就要多用 1 英寸的屏幕,所以這個色塊在屏幕上面看起來就“長大了”一倍。

dip設置與分辯率無關,但寫屏幕密度有關.在默認情況下,
LDPI密度為120,系數為0.75,
MDPI的密度為160,系數為1.0;
HDPI的密碼為240,系數為1.5;
XHDPI的密度為320,系數為2.0;
所謂密度即單位平方英寸中含像素的數量
一、基本概念
- dip : Density independent pixels ,設備無關像素。
- dp :就是dip
- px : 像素
- dpi :dots per inch , 直接來說就是一英寸多少個像素點。常見取值 120,160,240。我一般稱作像素密度,簡稱密度
- density : 直接翻譯的話貌似叫 密度。常見取值 1.5 , 1.0 。和標准dpi的比例(160px/inc)
- 分辨率 : 橫縱2個方向的像素點的數量,常見取值 480X800 ,320X480
- 屏幕尺寸: 屏幕對角線的長度。電腦電視同理。
- 屏幕比例的問題。因為只確定了對角線長,2邊長度還不一定。所以有了4:3、16:9這種,這樣就可以算出屏幕邊長了。
二、應用
在android里面,獲取一個窗口的metrics,里面有這么幾個值
metrics.density; metrics.densityDpi;
densityDpi : 就是我們常說的dpi。
density : 其實是 DPI / (160像素/英寸) 后得到的值。是不是有點奇怪,因為我帶了單位。。。這個涉及到后面一個比較重要的東西,后面再說。
從上面就看得出了,DPI本身的單位也是 像素/英寸,所以density其實是沒單位的,他就是一個比例值。
而dpi的單位是 像素/英寸,比較符合物理上面的密度定義,密度不都是單位度量的值么,所以我更喜歡把dpi叫像素密度,簡稱密度,density還是就叫density。
三、各單位間轉換
1. 計算dpi
比如一個機器,屏幕4寸,分辨率480X800,他的dpi能算么。
因為不知道邊長,肯定不能分開算,4是對角線長度,那直接用勾股定理算對角線像素,除以4,算出來大概是 dpi = 233 像素/英寸。
那么density就是 (233 px/inch)/(160 px/inch)=1.46 左右
順帶說下,android默認的只有3個dpi,low、medium和high,對應 120、160、240,如果沒有特別設置,所有的dpi都會被算成這3個,具體可以參考下這個帖子
http://android.tgbus.com/Android/tutorial/201103/347176.shtml
其中的default就是160。
2. 計算 dp 與 px
我們寫布局的時候,肯定還是要知道1個dp到底有多少px的。
換算公式如下: dp = (DPI/(160像素/英寸))px = density px
注意,這里都是帶單位的。px是單位,dp是單位,density沒單位。
為了方便,假設dpi是240 像素/英寸 , 那么density就是1.5
那么就是 dp=1.5px ,注意這是帶了單位的,也就是 設備無關像素 = density 像素
那么轉換為數值計算的話,應該是下面這個式子
PX = density * DP
也就是
像素值 = density * 設備無關像素值 ,請注意這里有個值字。
3. 為啥 標准dpi = 160
(1)Android Design [1] 里把主流設備的 dpi 歸成了四個檔次,120 dpi、160 dpi、240 dpi、320 dpi
實際開發當中,我們經常需要對這幾個尺寸進行相互轉換(比如先在某個分辨率下完成設計,然后縮放到其他尺寸微調后輸出),一般按照 dpi 之間的比例即 2:1.5:1:0.75 來給界面中的元素來進行尺寸定義。
也就是說如果以 160 dpi 作為基准的話,只要尺寸的 DP 是 4 的公倍數,XHDPI 下乘以 2,HDPI 下乘以 1.5,LDPI 下乘以 0.75 即可滿足所有尺寸下都是整數 pixel 。
但假設以 240 dpi 作為標准,那需要 DP 是 3 的公倍數,XHDPI 下乘以 1.333,MDPI 下乘以 0.666 ,LDPI 下除以 2
而以 LDPI 和 XHDPI 為基准就更復雜了,所以選擇 160 dpi
(2)這個在Google的官方文檔中有給出了解釋,因為第一款Android設備(HTC的T-Mobile G1)是屬於160dpi的。
四、 示例分析
1. 屏幕尺寸(screen size)
就是我們平常講的手機屏幕大小,是屏幕的對角線長度,一般講的大小單位都是英寸。
比如iPhone5S的屏幕尺寸是4英寸。Samsung Note3是5.7英寸。

圖 1
2.像素(pixel)
想像把屏幕放大再放大,對!看到的那一個個小點或者小方塊就是像素了。

圖 2
3.分辨率(Resolution)
是指屏幕上垂直方向和水平方向上的像素個數。
比如iPhone5S的分辨率是1136*640;Samsung Note3的分辨率是1920*1080;

圖 3
4.dpi
是dot per inch的縮寫,就是每英寸的像素數,也叫做屏幕密度。這個值越大,屏幕就越清晰。
iPhone5S的dpi是326; Samsung Note3 的dpi是386

圖 4
5.dip
是Density independent pixel的縮寫,指的是抽象意義上的像素。跟設備的屏幕密度有關系。
它是Android里的一個單位,dip和dp是一樣的。
Google的官方說明是這樣的:
密度獨立像素(dp)
在定義UI布局時,應該使用一個虛擬像素單元,以一種密度獨立的方式表示布局維度或位置。
密度無關的像素相當於一個物理像素在160 dpi屏幕上,這是系統為“中等”密度屏幕所假設的基線密度。在運行時,系統會根據實際的屏幕密度,透明地處理dp單元的任何擴展。將dp單元轉換為屏幕像素很簡單:px=dp(dpi/160)。例如,在240 dpi屏幕上,1 dp等於1。5物理像素。在定義應用程序的UI時,應該始終使用dp單元,以確保在具有不同密度的屏幕上正確顯示UI。
就是說在160dpi的屏幕上,1dip=1px。
它跟屏幕密度有關,如果屏幕密度大,1dip代表的px就多,比如在320dpi的屏幕上,1dip=2px。
為什么我們在布局的時候最好要用dip,不要用px?
是因為這個世界上存在着很多不同屏幕密度的手機,屏幕密度是什么?就是dpi,就是單位長度里的像素數量。
想象一下,如果這些手機的尺寸一樣,屏幕密度相差很大,那么是不是說一個手機水平方向上像素很少,另一個手機水平方向上像素很多?那我們畫同樣pix數量的時候,它顯
示的長度不就會不一樣了?
比如下面圖中的兩個手機,同時設置2px長度的Button,在屏幕密度較高的手機里就會顯示的比較小。
而同時設置的2dip長度的Button,在兩個手機上顯示的大小是一樣的。

圖 5
所以如果你在App布局中都用的px作為單位,那么你的App跑在各個設備上就會出現奇奇怪怪的現象了。
來看一下emulator上的效果,我定義了兩個Button,分別用px和dip做單位。
布局文件里這樣寫
<Button android:layout_width="100px"
android:layout_height="100px"
android:text="@string/str_button1"/>
<Button android:layout_width="100dip"
android:layout_height="100dip"
android:text="@string/str_button1"/>
顯示的界面是這樣的:

圖 6
getResources().getDisplayMetrics().densityDpi 就是屏幕密度。
getResources().getDisplayMetrics().density 也可以理解為1dip相當於多少個px啦。
上面的dpi是240,1dip=1.5px
你看,100dip的Button是100pxButton的1.5倍長吧。

