[Android] Android開發(fā)中dip硬纤,dpi解滓,density,px等詳解

Android開發(fā)中的各種單位的解釋


  • Px (Pixel像素)
    也稱為圖像元素筝家,是作為圖像構(gòu)成的基本單元洼裤,單個像素的大小并不固定,跟隨屏幕大小和像素數(shù)量的關(guān)系變化(屏幕越大溪王,像素越低腮鞍,單個像素越大,反之亦然)莹菱。所以在使用像素作為設(shè)計單位時移国,在不同的設(shè)備上可能會有縮放或拉伸的情況。

  • Resolution(分辨率)
    是指屏幕的垂直和水平方向的像素數(shù)量道伟,如果分辨率是 1920*1080 迹缀,那就是垂直方向有 1920 個像素使碾,水平方向有 1080 個像素。

  • Dpi(像素密度)
    是指屏幕上每英寸(1英寸 = 2.54 厘米)距離中有多少個像素點(diǎn)祝懂。如果屏幕為 320*240票摇,屏幕長 2 英寸寬 1.5 英寸,Dpi = 320 / 2 = 240 / 1.5 = 160砚蓬。

  • Density(密度)
    這個是指屏幕上每平方英寸(2.54 ^ 2 平方厘米)中含有的像素點(diǎn)數(shù)量矢门。

  • Dip / dp (設(shè)備獨(dú)立像素)
    也可以叫做dp,長度單位灰蛙,同一個單位在不同的設(shè)備上有不同的顯示效果颅和,具體效果根據(jù)設(shè)備的密度有關(guān),詳細(xì)的公式請看下面 缕允。

計算規(guī)則


我們以一個 4.95 英寸 1920 * 1080 的 nexus5 手機(jī)設(shè)備為例:

Dpi :

  1. 計算直角邊像素數(shù)量: 19202+10802=2202^2(勾股定理)峡扩。
  2. 計算 DPI:2202 / 4.95 = 445。
  3. 得到這個設(shè)備的 DPI 為 445 (每英寸的距離中有 445 個像素)障本。

Density

上面得到每英寸中有 440 像素教届,那么 density 為每平方英寸中的像素數(shù)量,應(yīng)該為: 445^2=198025驾霜。

Dip

  1. 先明白一個概念案训,所有顯示到屏幕上的圖像都是以 px 為單位。
  2. Dip 是我們開發(fā)中使用的長度單位粪糙,最后他也需要轉(zhuǎn)換成 px强霎。
  3. 計算這個設(shè)備上 1dip 等于多少 px:
    px = dip x dpi /160
    px = 1 x 445 / 160 = 2.78
  4. 通過上面的計算可以看出在此設(shè)備上 1dip = 2.78px,那么這是一個真實的故事嗎蓉冈? nonono城舞,其中的關(guān)鍵值 dpi 并不是我們算出來的 445 ,請往下看寞酿。

Android 系統(tǒng)定義的 Dpi


上面計算的 445Dpi 是在 4.95 英寸下的 1920*1080 手機(jī)家夺,那如果是 4.75 分辨率下的呢? 4.55 分辨率下的呢伐弹?拉馋。。惨好。煌茴。可見是很麻煩的日川,同一個分辨率在不同的屏幕尺寸上 Dpi 也不相同蔓腐。為了解決這個問題, Android 中內(nèi)置了幾個默認(rèn)的 Dpi 逗鸣,在特定的分辨率下自動調(diào)用合住,也可以手動在配置文件中修改绰精。

ldpi mdpi hdpi xhdpi xxhdpi
分辨率 240x320 320x480 480x800 720x1280 1080x1920
系統(tǒng)dpi 120 160 240 320 480
基準(zhǔn)比例 0.75 1 1.5 2 3

這是內(nèi)置的 Dpi 撒璧,啥意思透葛? 在 1920*1080 分辨率的手機(jī)上 默認(rèn)就使用 480 的 dpi ,不管的你的尺寸是多大都是這樣卿樱,除非廠家手動修改了配置文件僚害,這個我們后面再說。
我們親自嘗試一下:

<TextView    
  android:id="@+id/tv"   
  android:layout_width="200dp"    
  android:layout_height="100dp"    
  android:text="Hello World!" />

這是一個 textview繁调,高為 200dp 寬為 100dp 萨蚕。按照我們之前的公式手動計算:

height = 100 x 445 / 160 = 278.5px
width  = 200 x 445 / 160 = 556.25px

我們用下列代碼獲取到控件的實際像素看看是否相同:

layout = (RelativeLayout)findViewById(R.id.la);
//要在控件繪制完成后才能獲取到相關(guān)信息,所以這里要監(jiān)聽繪制狀態(tài)
layout.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener()     {    
  public boolean onPreDraw() {        
    Log.d("hehehe", textView.getHeight() + "/" + textView.getWidth());       
    return true;    
  }
});

輸出的結(jié)果為:300/600
內(nèi)部計算過程為:

height = 100 x 480 / 160 = 300px
width  = 200 x 480 / 160 = 600px

其中的 160 是基準(zhǔn)值不會變的蹄胰, 100 和200 是我們設(shè)置的 dp 岳遥,那么這 480 是從何而來的?說好的 445 呢裕寨?
找到我們手機(jī)中的 /system/build.prop 文件浩蓉,其中有一行是這樣:
ro.sf.lcd_density=480

這就指定了這個機(jī)型使用的dpi是多少,還有一種情況是沒有這一行(我在模擬器中發(fā)現(xiàn)過)宾袜,那么應(yīng)該是根據(jù)表格中的分辨率來自動設(shè)置捻艳。

我更改這行為:
ro.sf.lcd_density=320

再次運(yùn)行上面的測試代碼,輸出結(jié)果為:200/400
內(nèi)部計算過程為:

height = 100 x 320 / 160 = 200px
width  = 200 x 320 / 160 = 400px

說到底庆猫,因為有dpi這個動態(tài)的系數(shù)认轨,我們在使用dp的時候才能兼容不同分辨率的設(shè)備。

到這里月培,應(yīng)該都明白了 dpi 的由來嘁字,以及系統(tǒng) dpi 跟物理 dpi 并不一定相同。在系統(tǒng)中使用的全部都是系統(tǒng) dpi杉畜,沒有使用物理 dpi拳锚,也獲取不到物理 dpi。物理 dpi 主要用于廠家對于手機(jī)的參數(shù)描述(也可以看做 ppi )寻行!

然后霍掺。。表格中還有一個東西叫做基準(zhǔn)比例拌蜘,這個其實就是計算 dp -> px 中重要的系數(shù)杆烁,以 160 為基準(zhǔn),其他的除以 160 得到比例简卧,我們這樣看:

height = 100 x 480 / 160 = 300px
width  = 200 x 480 / 160 = 600px

其中的480/160其實就是在求基準(zhǔn)比例兔魂,這里得到3。如果在熟悉上表的情況下看到機(jī)型的分辨率举娩,在設(shè)置dp的時候可以直接心算出相對應(yīng)的px析校,心算過程如下:

分辨率:1080x1920 -> 系統(tǒng) DPI:480 -> 基準(zhǔn)比例:480 / 160 = 3 -> 對應(yīng)px:100 x 3 = 300
分辨率:720x1280 -> 系統(tǒng) DPI:320 -> 基準(zhǔn)比例:320 / 160 = 2 -> 對應(yīng)px:100 x 2 = 200
分辨率:480x800 -> 系統(tǒng) DPI:240 -> 基準(zhǔn)比例:240 / 160 = 1.5 -> 對應(yīng)px:100 x 1.5 = 150
分辨率:320x480 -> 系統(tǒng) DPI:160 -> 基準(zhǔn)比例:160 / 160 = 1 -> 對應(yīng)px:100 x 1 = 100
分辨率:240x320 -> 系統(tǒng) DPI:120 -> 基準(zhǔn)比例:120 / 160 = 0.75 -> 對應(yīng)px:100 x 0.75 = 75
...................

總結(jié):

1. dpi(每英寸像素數(shù))是有預(yù)設(shè)值的构罗!120-160-240-320-480。對應(yīng)不同的分辨率智玻。

2. 基準(zhǔn)比例 = dpi(每英寸像素數(shù)) / 160

3. px = dp x 基準(zhǔn)比例

從代碼中獲取相關(guān)數(shù)值


我們主要使用的類是:DisplayMetrics

以下為官方api說明
A structure describing general information about a display, such as its size, density, and font scaling.
To access the DisplayMetrics members, initialize an object like this:

DisplayMetrics metrics = newDisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

這是一個獲取屏幕信息的類遂唧,比如大小,密度等吊奢。以及初始化的方法盖彭。

實際運(yùn)用如下:

DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
//通常我們在使用DisplayMetrics時,都是直接獲取內(nèi)部變量來使用页滚。所以下面直接列出各個內(nèi)部變量召边。

dm.ydpi;     //得到物理屏幕上 Y 軸方向每英寸的像素
dm.xdpi;     //得到物理屏幕上 X 軸方向每英寸的像素 
             //ps:  其實這兩個大多數(shù)情況下都是相同的
             //你能想象上面像素密度大很清晰 下面密度小跟馬賽克一樣嗎 233333

dm.density;           //獲取當(dāng)前設(shè)備的基準(zhǔn)比例
dm.densityDpi;        //獲取系統(tǒng)dpi,隨著 build.prop 文件中的代碼而改變裹驰。

dm.widthPixels;       //獲取屏幕寬度的像素數(shù)量

//獲取屏幕高度的像素數(shù)量隧熙!
//注意 - 因為這里會自動減去32dp的像素數(shù)量,根據(jù)分辨率不同的設(shè)備幻林,減去的像素數(shù)量也不同贞盯,但是可以根據(jù)公式推算完整(px = dp x 基準(zhǔn)比例)。
/*為啥不用dm.densityDpi / 160 得到基準(zhǔn)比例滋将?
  因為那個會隨著build.prop文件代碼變更而更改邻悬,算出來的不一定準(zhǔn)確*/
dm.heightPixels + 32 * dm.ydpi / 160;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市随闽,隨后出現(xiàn)的幾起案子父丰,更是在濱河造成了極大的恐慌,老刑警劉巖掘宪,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蛾扇,死亡現(xiàn)場離奇詭異,居然都是意外死亡魏滚,警方通過查閱死者的電腦和手機(jī)镀首,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鼠次,“玉大人更哄,你說我怎么就攤上這事⌒瓤埽” “怎么了成翩?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長赦役。 經(jīng)常有香客問我麻敌,道長,這世上最難降的妖魔是什么掂摔? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任术羔,我火速辦了婚禮赢赊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘级历。我一直安慰自己释移,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布鱼喉。 她就那樣靜靜地躺著秀鞭,像睡著了一般趋观。 火紅的嫁衣襯著肌膚如雪扛禽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天皱坛,我揣著相機(jī)與錄音编曼,去河邊找鬼。 笑死剩辟,一個胖子當(dāng)著我的面吹牛掐场,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播贩猎,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼熊户,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了吭服?” 一聲冷哼從身側(cè)響起嚷堡,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎艇棕,沒想到半個月后蝌戒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡沼琉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年北苟,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片打瘪。...
    茶點(diǎn)故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡友鼻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出闺骚,到底是詐尸還是另有隱情彩扔,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布葛碧,位于F島的核電站借杰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏进泼。R本人自食惡果不足惜蔗衡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一纤虽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧绞惦,春花似錦逼纸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至王滤,卻和暖如春贺嫂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背雁乡。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工第喳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人踱稍。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓曲饱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親珠月。 傳聞我的和親對象是個殘疾皇子扩淀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容